quickjs-tart

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

commit 07af9c8add3806f396b141d9f66b986e60af26f2
parent 702fa92a4a475bbfae15858e670c1d8fbfbdf6bd
Author: Florian Dold <florian@dold.me>
Date:   Mon, 17 Mar 2025 12:44:45 +0100

code style

Diffstat:
Mtart_module.c | 1035++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 519 insertions(+), 516 deletions(-)

diff --git a/tart_module.c b/tart_module.c @@ -54,12 +54,12 @@ static JSValue js_random_bytes(JSContext *ctx, JSValueConst this_val, uint32_t nbytes; JSValue buf; if (0 != JS_ToUint32(ctx, &nbytes, argv[0])) { - return JS_EXCEPTION; + return JS_EXCEPTION; } { - uint8_t randbuf[nbytes]; - randombytes_buf (randbuf, nbytes); - buf = JS_NewArrayBufferCopy(ctx, randbuf, nbytes); + uint8_t randbuf[nbytes]; + randombytes_buf (randbuf, nbytes); + buf = JS_NewArrayBufferCopy(ctx, randbuf, nbytes); } return buf; } @@ -74,218 +74,220 @@ static JSValue js_random_bytes(JSContext *ctx, JSValueConst this_val, static unsigned int getValue__ (unsigned char a) { - unsigned int dec; - - switch (a) - { - case 'O': - case 'o': - a = '0'; - break; - - case 'i': - case 'I': - case 'l': - case 'L': - a = '1'; - break; - - /* also consider U to be V */ - case 'u': - case 'U': - a = 'V'; - break; - - default: - break; - } - if ((a >= '0') && (a <= '9')) - return a - '0'; - if ((a >= 'a') && (a <= 'z')) - a = toupper (a); - /* return (a - 'a' + 10); */ - dec = 0; - if ((a >= 'A') && (a <= 'Z')) - { - if ('I' < a) - dec++; - if ('L' < a) - dec++; - if ('O' < a) - dec++; - if ('U' < a) - dec++; - return(a - 'A' + 10 - dec); - } - return -1; + unsigned int dec; + + switch (a) + { + case 'O': + case 'o': + a = '0'; + break; + + case 'i': + case 'I': + case 'l': + case 'L': + a = '1'; + break; + + /* also consider U to be V */ + case 'u': + case 'U': + a = 'V'; + break; + + default: + break; + } + if ((a >= '0') && (a <= '9')) + return a - '0'; + if ((a >= 'a') && (a <= 'z')) + a = toupper (a); + /* return (a - 'a' + 10); */ + dec = 0; + if ((a >= 'A') && (a <= 'Z')) + { + if ('I' < a) + dec++; + if ('L' < a) + dec++; + if ('O' < a) + dec++; + if ('U' < a) + dec++; + return(a - 'A' + 10 - dec); + } + return -1; } static JSValue js_talercrypto_encode_crock(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - size_t size; - uint8_t *buf; - uint8_t *out = NULL; - size_t out_size; - // 32 characters for encoding - static char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; - unsigned int wpos; - unsigned int rpos; - unsigned int bits; - unsigned int vbit; - const unsigned char *udata; - JSValue ret_val; - - ret_val = JS_UNDEFINED; - - buf = JS_GetArrayBuffer(ctx, &size, argv[0]); - - if (!buf) { - goto exception; - } - - assert (size < SIZE_MAX / 8 - 4); - out_size = size * 8; - - if (out_size % 5 > 0) - out_size += 5 - out_size % 5; - out_size /= 5; - - out = malloc (out_size + 1); - memset (out, 0, out_size + 1); - if (!out) { - goto exception; - } - - udata = buf; - if (out_size < (size * 8 + 4) / 5) { - goto exception; - } - vbit = 0; - wpos = 0; - rpos = 0; - bits = 0; - while ((rpos < size) || (vbit > 0)) - { - if ((rpos < size) && (vbit < 5)) - { - bits = (bits << 8) | udata[rpos++]; /* eat 8 more bits */ - vbit += 8; + size_t size; + uint8_t *buf; + uint8_t *out = NULL; + size_t out_size; + // 32 characters for encoding + static char *encTable__ = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; + unsigned int wpos; + unsigned int rpos; + unsigned int bits; + unsigned int vbit; + const unsigned char *udata; + JSValue ret_val; + + ret_val = JS_UNDEFINED; + + buf = JS_GetArrayBuffer(ctx, &size, argv[0]); + + if (!buf) { + goto exception; } - if (vbit < 5) - { - bits <<= (5 - vbit); /* zero-padding */ - assert (vbit == ((size * 8) % 5)); - vbit = 5; + + assert (size < SIZE_MAX / 8 - 4); + out_size = size * 8; + + if (out_size % 5 > 0) + out_size += 5 - out_size % 5; + out_size /= 5; + + out = malloc (out_size + 1); + memset (out, 0, out_size + 1); + if (!out) { + goto exception; } - if (wpos >= out_size) + + udata = buf; + if (out_size < (size * 8 + 4) / 5) { + goto exception; + } + vbit = 0; + wpos = 0; + rpos = 0; + bits = 0; + while ((rpos < size) || (vbit > 0)) { - goto exception; + if ((rpos < size) && (vbit < 5)) + { + /* eat 8 more bits */ + bits = (bits << 8) | udata[rpos++]; + vbit += 8; + } + if (vbit < 5) + { + bits <<= (5 - vbit); /* zero-padding */ + assert (vbit == ((size * 8) % 5)); + vbit = 5; + } + if (wpos >= out_size) + { + goto exception; + } + out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31]; + vbit -= 5; + } + assert (0 == vbit); + if (wpos < out_size) { + out[wpos] = '\0'; } - out[wpos++] = encTable__[(bits >> (vbit - 5)) & 31]; - vbit -= 5; - } - assert (0 == vbit); - if (wpos < out_size) - out[wpos] = '\0'; - ret_val = JS_NewString(ctx, (char *) out); + ret_val = JS_NewString(ctx, (char *) out); done: - if (NULL != out) { - free(out); - } - return ret_val; + if (NULL != out) { + free(out); + } + return ret_val; exception: - ret_val = JS_EXCEPTION; - goto done; + ret_val = JS_EXCEPTION; + goto done; } static JSValue js_talercrypto_decode_crock(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - size_t rpos; - size_t wpos; - unsigned int bits; - unsigned int vbit; - int ret; - int shift; - size_t enclen; - size_t encoded_len; - const char *enc; - JSValue ret_val = JS_UNDEFINED; - unsigned char *uout = NULL; - size_t out_size; - JSValue abuf; - - enc = JS_ToCStringLen2(ctx, &enclen, argv[0], FALSE); - if (!enc) { - goto exception; - } - - out_size = (enclen * 5) / 8; - encoded_len = out_size * 8; - uout = malloc(out_size); - assert (out_size < SIZE_MAX / 8); - wpos = out_size; - rpos = enclen; - if ((encoded_len % 5) > 0) - { - vbit = encoded_len % 5; /* padding! */ - shift = 5 - vbit; - bits = (ret = getValue__ (enc[--rpos])) >> shift; - } - else - { - vbit = 5; - shift = 0; - bits = (ret = getValue__ (enc[--rpos])); - } - if ((encoded_len + shift) / 5 != enclen) { - JS_ThrowTypeError(ctx, "wrong encoded length"); - goto exception; - } - - if (-1 == ret) { - JS_ThrowTypeError(ctx, "invalid character in encoding"); - goto exception; - } - while (wpos > 0) - { - if (0 == rpos) + size_t rpos; + size_t wpos; + unsigned int bits; + unsigned int vbit; + int ret; + int shift; + size_t enclen; + size_t encoded_len; + const char *enc; + JSValue ret_val = JS_UNDEFINED; + unsigned char *uout = NULL; + size_t out_size; + JSValue abuf; + + enc = JS_ToCStringLen2(ctx, &enclen, argv[0], FALSE); + if (!enc) { + goto exception; + } + + out_size = (enclen * 5) / 8; + encoded_len = out_size * 8; + uout = malloc(out_size); + assert (out_size < SIZE_MAX / 8); + wpos = out_size; + rpos = enclen; + if ((encoded_len % 5) > 0) { - goto exception; + vbit = encoded_len % 5; /* padding! */ + shift = 5 - vbit; + bits = (ret = getValue__ (enc[--rpos])) >> shift; } - bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits; + else + { + vbit = 5; + shift = 0; + bits = (ret = getValue__ (enc[--rpos])); + } + if ((encoded_len + shift) / 5 != enclen) { + JS_ThrowTypeError(ctx, "wrong encoded length"); + goto exception; + } + if (-1 == ret) { - goto exception; + JS_ThrowTypeError(ctx, "invalid character in encoding"); + goto exception; } - vbit += 5; - if (vbit >= 8) + while (wpos > 0) { - uout[--wpos] = (unsigned char) bits; - bits >>= 8; - vbit -= 8; - } - } - if ((0 != rpos) || (0 != vbit)) { - JS_ThrowTypeError(ctx, "rpos or vbit not zero"); - goto exception; - } - abuf = JS_NewArrayBufferCopy(ctx, uout, out_size); - if (JS_IsException(abuf)) { - goto exception; - } - ret_val = JS_NewTypedArraySimple(ctx, abuf, 1); + if (0 == rpos) + { + goto exception; + } + bits = ((ret = getValue__ (enc[--rpos])) << vbit) | bits; + if (-1 == ret) { + goto exception; + } + vbit += 5; + if (vbit >= 8) + { + uout[--wpos] = (unsigned char) bits; + bits >>= 8; + vbit -= 8; + } + } + if ((0 != rpos) || (0 != vbit)) { + JS_ThrowTypeError(ctx, "rpos or vbit not zero"); + goto exception; + } + abuf = JS_NewArrayBufferCopy(ctx, uout, out_size); + if (JS_IsException(abuf)) { + goto exception; + } + ret_val = JS_NewTypedArraySimple(ctx, abuf, 1); done: - JS_FreeCString(ctx, enc); - if (uout) { - free(uout); - } - return ret_val; + JS_FreeCString(ctx, enc); + if (uout) { + free(uout); + } + return ret_val; exception: - ret_val = JS_EXCEPTION; - goto done; + ret_val = JS_EXCEPTION; + goto done; } uint8_t *expect_fixed_buffer(JSContext *ctx, @@ -328,8 +330,8 @@ expect_mpi(JSContext *ctx, #define CHECK(x) do { if (!(x)) { abort(); } } while (0) typedef struct { - mbedtls_mpi N; - mbedtls_mpi e; + mbedtls_mpi N; + mbedtls_mpi e; } RsaPub; typedef uint8_t BlindingKeySecret[32]; @@ -373,9 +375,9 @@ cleanup: int expect_rsa_pub(JSContext *ctx, - JSValue val, - const char *msg, - RsaPub *ret_rsa_pub) + JSValue val, + const char *msg, + RsaPub *ret_rsa_pub) { uint8_t *rsa_enc; size_t rsa_enc_len; @@ -399,13 +401,13 @@ cleanup: static JSValue make_js_ta_copy(JSContext *ctx, uint8_t *data, size_t size) { - JSValue array_buf; + JSValue array_buf; - array_buf = JS_NewArrayBufferCopy(ctx, data, size); - if (JS_IsException(array_buf)) { - return JS_EXCEPTION; - } - return JS_NewTypedArraySimple(ctx, array_buf, 1); + array_buf = JS_NewArrayBufferCopy(ctx, data, size); + if (JS_IsException(array_buf)) { + return JS_EXCEPTION; + } + return JS_NewTypedArraySimple(ctx, array_buf, 1); } /** @@ -447,17 +449,17 @@ cleanup: static JSValue js_talercrypto_hash(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - size_t size; - uint8_t *buf; - unsigned char h[crypto_hash_BYTES]; + size_t size; + uint8_t *buf; + unsigned char h[crypto_hash_BYTES]; - buf = JS_GetArrayBuffer(ctx, &size, argv[0]); - if (!buf) { - return JS_EXCEPTION; - } - crypto_hash_sha512(h, buf, size); + buf = JS_GetArrayBuffer(ctx, &size, argv[0]); + if (!buf) { + return JS_EXCEPTION; + } + crypto_hash_sha512(h, buf, size); - return make_js_ta_copy(ctx, h, crypto_hash_BYTES); + return make_js_ta_copy(ctx, h, crypto_hash_BYTES); } static JSValue js_talercrypto_hash_argon2id(JSContext *ctx, JSValue this_val, @@ -532,40 +534,40 @@ static JSValue js_talercrypto_hash_argon2id(JSContext *ctx, JSValue this_val, static JSValue js_talercrypto_eddsa_key_get_public(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - uint8_t *buf; - unsigned char pk[crypto_sign_PUBLICKEYBYTES]; - unsigned char sk[crypto_sign_SECRETKEYBYTES]; + uint8_t *buf; + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + unsigned char sk[crypto_sign_SECRETKEYBYTES]; - buf = expect_fixed_buffer(ctx, argv[0], 32, "eddsa private key"); - - if (!buf) { - return JS_EXCEPTION; - } + buf = expect_fixed_buffer(ctx, argv[0], 32, "eddsa private key"); + + if (!buf) { + return JS_EXCEPTION; + } - crypto_sign_seed_keypair(pk, sk, buf); - // FIXME: clean up stack! + crypto_sign_seed_keypair(pk, sk, buf); + // FIXME: clean up stack! - return make_js_ta_copy(ctx, pk, crypto_sign_PUBLICKEYBYTES); + return make_js_ta_copy(ctx, pk, crypto_sign_PUBLICKEYBYTES); } static JSValue js_talercrypto_ecdhe_key_get_public(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - uint8_t *buf; - unsigned char pk[crypto_scalarmult_BYTES]; + uint8_t *buf; + unsigned char pk[crypto_scalarmult_BYTES]; - buf = expect_fixed_buffer(ctx, argv[0], 32, "ecdh private key"); - - if (!buf) { - return JS_EXCEPTION; - } + buf = expect_fixed_buffer(ctx, argv[0], 32, "ecdh private key"); + + if (!buf) { + return JS_EXCEPTION; + } - if (0 != crypto_scalarmult_base(pk, buf)) { - return JS_EXCEPTION; - } - // FIXME: clean up stack! + if (0 != crypto_scalarmult_base(pk, buf)) { + return JS_EXCEPTION; + } + // FIXME: clean up stack! - return make_js_ta_copy(ctx, pk, crypto_sign_PUBLICKEYBYTES); + return make_js_ta_copy(ctx, pk, crypto_sign_PUBLICKEYBYTES); } /** @@ -617,35 +619,35 @@ static JSValue js_talercrypto_eddsa_sign(JSContext *ctx, JSValue this_val, static JSValue js_talercrypto_eddsa_verify(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - unsigned char *msg; - size_t msg_size; - unsigned char *sig; - size_t sig_size; - unsigned char *pub; - size_t pub_size; - int res; - - msg = JS_GetArrayBuffer(ctx, &msg_size, argv[0]); - if (!msg) { - return JS_EXCEPTION; - } - sig = JS_GetArrayBuffer(ctx, &sig_size, argv[1]); - if (!sig) { - return JS_EXCEPTION; - } - if (sig_size != 64) { - return JS_ThrowTypeError(ctx, "invalid signature size"); - } - pub = JS_GetArrayBuffer(ctx, &pub_size, argv[2]); - if (!pub) { - return JS_EXCEPTION; - } - if (pub_size != 32) { - return JS_ThrowTypeError(ctx, "invalid public key size"); - } - - res = crypto_sign_verify_detached (sig, msg, msg_size, pub); - return (res == 0) ? JS_TRUE : JS_FALSE; + unsigned char *msg; + size_t msg_size; + unsigned char *sig; + size_t sig_size; + unsigned char *pub; + size_t pub_size; + int res; + + msg = JS_GetArrayBuffer(ctx, &msg_size, argv[0]); + if (!msg) { + return JS_EXCEPTION; + } + sig = JS_GetArrayBuffer(ctx, &sig_size, argv[1]); + if (!sig) { + return JS_EXCEPTION; + } + if (sig_size != 64) { + return JS_ThrowTypeError(ctx, "invalid signature size"); + } + pub = JS_GetArrayBuffer(ctx, &pub_size, argv[2]); + if (!pub) { + return JS_EXCEPTION; + } + if (pub_size != 32) { + return JS_ThrowTypeError(ctx, "invalid public key size"); + } + + res = crypto_sign_verify_detached (sig, msg, msg_size, pub); + return (res == 0) ? JS_TRUE : JS_FALSE; } /** @@ -755,35 +757,35 @@ exception: static JSValue js_talercrypto_kx_ecdh_eddsa(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - JSValue ret_val; - uint8_t p[crypto_scalarmult_BYTES]; - uint8_t *ecdh_priv; - uint8_t *eddsa_pub; - uint8_t curve25510_pk[crypto_scalarmult_BYTES]; - uint8_t key_material[crypto_hash_BYTES]; - - ecdh_priv = expect_fixed_buffer(ctx, argv[0], 32, "ecdhe priv"); - REQUIRE(ecdh_priv, exception); - - eddsa_pub = expect_fixed_buffer(ctx, argv[1], 32, "eddsa pub"); - REQUIRE(eddsa_pub, exception); - - if (0 != crypto_sign_ed25519_pk_to_curve25519(curve25510_pk, eddsa_pub)) { - goto exception; - } - if (0 != crypto_scalarmult(p, ecdh_priv, curve25510_pk)) { - goto exception; - } - if (0 != crypto_hash(key_material, p, 32)) { - JS_ThrowTypeError(ctx, "hashing failed"); - goto exception; - } - ret_val = make_js_ta_copy(ctx, key_material, crypto_hash_BYTES); + JSValue ret_val; + uint8_t p[crypto_scalarmult_BYTES]; + uint8_t *ecdh_priv; + uint8_t *eddsa_pub; + uint8_t curve25510_pk[crypto_scalarmult_BYTES]; + uint8_t key_material[crypto_hash_BYTES]; + + ecdh_priv = expect_fixed_buffer(ctx, argv[0], 32, "ecdhe priv"); + REQUIRE(ecdh_priv, exception); + + eddsa_pub = expect_fixed_buffer(ctx, argv[1], 32, "eddsa pub"); + REQUIRE(eddsa_pub, exception); + + if (0 != crypto_sign_ed25519_pk_to_curve25519(curve25510_pk, eddsa_pub)) { + goto exception; + } + if (0 != crypto_scalarmult(p, ecdh_priv, curve25510_pk)) { + goto exception; + } + if (0 != crypto_hash(key_material, p, 32)) { + JS_ThrowTypeError(ctx, "hashing failed"); + goto exception; + } + ret_val = make_js_ta_copy(ctx, key_material, crypto_hash_BYTES); done: - return ret_val; + return ret_val; exception: - ret_val = JS_EXCEPTION; - goto done; + ret_val = JS_EXCEPTION; + goto done; } /** @@ -792,31 +794,31 @@ exception: static JSValue js_talercrypto_kx_eddsa_ecdh(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - JSValue ret_val; - uint8_t *priv; - uint8_t *pub; - uint8_t hc[crypto_hash_BYTES]; - uint8_t a[crypto_scalarmult_SCALARBYTES]; - uint8_t p[crypto_scalarmult_BYTES]; - uint8_t key_material[crypto_hash_BYTES]; - - priv = expect_fixed_buffer(ctx, argv[0], 32, "eddsa priv"); - REQUIRE(priv, exception); - pub = expect_fixed_buffer(ctx, argv[1], 32, "ecdh pub"); - REQUIRE(pub, exception); - - crypto_hash(hc, priv, 32); - memcpy (a, &hc, 32); - if (0 != crypto_scalarmult(p, a, pub)) { - goto exception; - } - crypto_hash(key_material, p, crypto_scalarmult_BYTES); - ret_val = make_js_ta_copy(ctx, key_material, crypto_hash_BYTES); + JSValue ret_val; + uint8_t *priv; + uint8_t *pub; + uint8_t hc[crypto_hash_BYTES]; + uint8_t a[crypto_scalarmult_SCALARBYTES]; + uint8_t p[crypto_scalarmult_BYTES]; + uint8_t key_material[crypto_hash_BYTES]; + + priv = expect_fixed_buffer(ctx, argv[0], 32, "eddsa priv"); + REQUIRE(priv, exception); + pub = expect_fixed_buffer(ctx, argv[1], 32, "ecdh pub"); + REQUIRE(pub, exception); + + crypto_hash(hc, priv, 32); + memcpy (a, &hc, 32); + if (0 != crypto_scalarmult(p, a, pub)) { + goto exception; + } + crypto_hash(key_material, p, crypto_scalarmult_BYTES); + ret_val = make_js_ta_copy(ctx, key_material, crypto_hash_BYTES); done: - return ret_val; + return ret_val; exception: - ret_val = JS_EXCEPTION; - goto done; + ret_val = JS_EXCEPTION; + goto done; } /** FIXME: Should return int */ @@ -827,47 +829,47 @@ kdf_mod_mpi(mbedtls_mpi *r, const void *skm, size_t skm_len, const char *ctx) { - int rc; - size_t nbits; - uint16_t ctr; - size_t ctxlen = strlen(ctx); - size_t my_ctx_len = ctxlen + 2; - unsigned char *my_ctx = malloc(my_ctx_len); - uint16_t *ctr_nbo_p = (uint16_t *) (my_ctx + ctxlen); - - memcpy(my_ctx, ctx, ctxlen); - - nbits = mbedtls_mpi_bitlen(n); - ctr = 0; - while (1) { - /* Not clear if n is always divisible by 8 */ - size_t bsize = (nbits - 1) / 8 + 1; - uint8_t buf[bsize]; - - *ctr_nbo_p = htons (ctr); - - rc = kdf (buf, bsize, - skm, skm_len, - xts, xts_len, - my_ctx, my_ctx_len); - CHECK(0 == rc); - rc = mbedtls_mpi_read_binary(r, buf, bsize); - CHECK(0 == rc); + int rc; + size_t nbits; + uint16_t ctr; + size_t ctxlen = strlen(ctx); + size_t my_ctx_len = ctxlen + 2; + unsigned char *my_ctx = malloc(my_ctx_len); + uint16_t *ctr_nbo_p = (uint16_t *) (my_ctx + ctxlen); + + memcpy(my_ctx, ctx, ctxlen); + + nbits = mbedtls_mpi_bitlen(n); + ctr = 0; while (1) { - size_t rlen = mbedtls_mpi_bitlen(r); - if (rlen <= nbits) { - break; - } - mbedtls_mpi_set_bit(r, rlen - 1, 0); - } - ++ctr; - /* We reject this FDH if either r > n and retry with another ctr */ - if (0 > mbedtls_mpi_cmp_mpi (r, n)) { - break; + /* Not clear if n is always divisible by 8 */ + size_t bsize = (nbits - 1) / 8 + 1; + uint8_t buf[bsize]; + + *ctr_nbo_p = htons (ctr); + + rc = kdf (buf, bsize, + skm, skm_len, + xts, xts_len, + my_ctx, my_ctx_len); + CHECK(0 == rc); + rc = mbedtls_mpi_read_binary(r, buf, bsize); + CHECK(0 == rc); + while (1) { + size_t rlen = mbedtls_mpi_bitlen(r); + if (rlen <= nbits) { + break; + } + mbedtls_mpi_set_bit(r, rlen - 1, 0); + } + ++ctr; + /* We reject this FDH if either r > n and retry with another ctr */ + if (0 > mbedtls_mpi_cmp_mpi (r, n)) { + break; + } + mbedtls_mpi_free (r); } - mbedtls_mpi_free (r); - } - free(my_ctx); + free(my_ctx); } @@ -886,21 +888,21 @@ static int rsa_gcd_validate (mbedtls_mpi *r, const mbedtls_mpi *n) { - mbedtls_mpi g; - int ret; + mbedtls_mpi g; + int ret; - mbedtls_mpi_init(&g); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&g, r, n)); + mbedtls_mpi_init(&g); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&g, r, n)); - if (mbedtls_mpi_cmp_int(&g, 1) == 0) { - ret = 0; - } else { - goto cleanup; - } + if (mbedtls_mpi_cmp_int(&g, 1) == 0) { + ret = 0; + } else { + goto cleanup; + } cleanup: - mbedtls_mpi_free(&g); - return ret; + mbedtls_mpi_free(&g); + return ret; } @@ -977,11 +979,11 @@ rsa_public_key_init(RsaPub *pkey) void rsa_public_key_free(RsaPub *pkey) { - if (!pkey) { - return; - } - mbedtls_mpi_free(&pkey->e); - mbedtls_mpi_free(&pkey->N); + if (!pkey) { + return; + } + mbedtls_mpi_free(&pkey->e); + mbedtls_mpi_free(&pkey->N); } @@ -989,71 +991,71 @@ int rsa_full_domain_hash (mbedtls_mpi *r, const RsaPub *pkey, const HashCode *hash) { - uint8_t *xts; - size_t xts_len; - - /* We key with the public denomination key as a homage to RSA-PSS by - Mihir Bellare and Phillip Rogaway. Doing this lowers the degree - of the hypothetical polyomial-time attack on RSA-KTI created by a - polynomial-time one-more forgary attack. Yey seeding! */ - rsa_public_key_encode(pkey, &xts, &xts_len); - - kdf_mod_mpi(r, - &pkey->N, - xts, xts_len, - hash, sizeof(*hash), - "RSA-FDA FTpsW!"); - free(xts); - if (0 == rsa_gcd_validate (r, &pkey->N)) { - return 0; - } - return 1; + uint8_t *xts; + size_t xts_len; + + /* We key with the public denomination key as a homage to RSA-PSS by + Mihir Bellare and Phillip Rogaway. Doing this lowers the degree + of the hypothetical polyomial-time attack on RSA-KTI created by a + polynomial-time one-more forgary attack. Yey seeding! */ + rsa_public_key_encode(pkey, &xts, &xts_len); + + kdf_mod_mpi(r, + &pkey->N, + xts, xts_len, + hash, sizeof(*hash), + "RSA-FDA FTpsW!"); + free(xts); + if (0 == rsa_gcd_validate (r, &pkey->N)) { + return 0; + } + return 1; } -int +static int rsa_blind(const HashCode *hash, const BlindingKeySecret *bks, const RsaPub *pkey, uint8_t **buf, size_t *buf_size) { - mbedtls_mpi bkey, data, r_e, data_r_e; - size_t outsize; - uint8_t *outbuf; - int ret; + mbedtls_mpi bkey, data, r_e, data_r_e; + size_t outsize; + uint8_t *outbuf; + int ret; - CHECK(buf != NULL); - CHECK(buf_size != NULL); + CHECK(buf != NULL); + CHECK(buf_size != NULL); - *buf = NULL; - *buf_size = 0; + *buf = NULL; + *buf_size = 0; - mbedtls_mpi_init(&bkey); - mbedtls_mpi_init(&data); - mbedtls_mpi_init(&r_e); - mbedtls_mpi_init(&data_r_e); + mbedtls_mpi_init(&bkey); + mbedtls_mpi_init(&data); + mbedtls_mpi_init(&r_e); + mbedtls_mpi_init(&data_r_e); - MBEDTLS_MPI_CHK(rsa_full_domain_hash (&data, pkey, hash)); - MBEDTLS_MPI_CHK(rsa_blinding_key_derive (&bkey, pkey, bks)); - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&r_e, &bkey, &pkey->e, &pkey->N, NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&data_r_e, &data, &r_e)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&data_r_e, &data_r_e, &pkey->N)); + MBEDTLS_MPI_CHK(rsa_full_domain_hash (&data, pkey, hash)); + MBEDTLS_MPI_CHK(rsa_blinding_key_derive (&bkey, pkey, bks)); + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&r_e, &bkey, &pkey->e, &pkey->N, NULL)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&data_r_e, &data, &r_e)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&data_r_e, &data_r_e, &pkey->N)); - outsize = (mbedtls_mpi_bitlen(&data_r_e) + 7) / 8; - outbuf = malloc(outsize); + outsize = (mbedtls_mpi_bitlen(&data_r_e) + 7) / 8; + outbuf = malloc(outsize); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&data_r_e, outbuf, outsize)); + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&data_r_e, outbuf, outsize)); - *buf = outbuf; - *buf_size = outsize; - ret = 0; + *buf = outbuf; + *buf_size = outsize; + ret = 0; cleanup: - mbedtls_mpi_free(&data); - mbedtls_mpi_free(&bkey); - mbedtls_mpi_free(&r_e); - mbedtls_mpi_free(&data_r_e); - return ret; + mbedtls_mpi_free(&data); + mbedtls_mpi_free(&bkey); + mbedtls_mpi_free(&r_e); + mbedtls_mpi_free(&data_r_e); + return ret; } int @@ -1062,23 +1064,23 @@ rsa_unblind (const mbedtls_mpi *sig_blinded, const RsaPub *pkey, mbedtls_mpi *sig_ret) { - mbedtls_mpi bkey, r_inv, ubsig; - int ret; + mbedtls_mpi bkey, r_inv, ubsig; + int ret; - mbedtls_mpi_init(&bkey); - mbedtls_mpi_init(&r_inv); - mbedtls_mpi_init(&ubsig); + mbedtls_mpi_init(&bkey); + mbedtls_mpi_init(&r_inv); + mbedtls_mpi_init(&ubsig); - MBEDTLS_MPI_CHK(rsa_blinding_key_derive (&bkey, pkey, bks)); - MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&r_inv, &bkey, &pkey->N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ubsig, sig_blinded, &r_inv)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(sig_ret, &ubsig)); + MBEDTLS_MPI_CHK(rsa_blinding_key_derive (&bkey, pkey, bks)); + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&r_inv, &bkey, &pkey->N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ubsig, sig_blinded, &r_inv)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(sig_ret, &ubsig)); cleanup: - mbedtls_mpi_free(&bkey); - mbedtls_mpi_free(&r_inv); - mbedtls_mpi_free(&ubsig); - return ret; + mbedtls_mpi_free(&bkey); + mbedtls_mpi_free(&r_inv); + mbedtls_mpi_free(&ubsig); + return ret; } @@ -1161,8 +1163,8 @@ static JSValue js_talercrypto_rsa_blind(JSContext *ctx, JSValueConst this_val, ret_val = make_js_ta_copy(ctx, out_buf, out_len); cleanup: if (NULL != out_buf) { - free(out_buf); - out_buf = NULL; + free(out_buf); + out_buf = NULL; } rsa_public_key_free(&rsa_pub); return ret_val; @@ -1286,7 +1288,7 @@ static JSValue js_structured_clone(JSContext *ctx, JSValueConst this_val, buf = JS_WriteObject(ctx, &len, argv[0], JS_WRITE_OBJ_REFERENCE); if (NULL == buf) { - return JS_EXCEPTION; + return JS_EXCEPTION; } obj = JS_ReadObject(ctx, buf, len, JS_WRITE_OBJ_REFERENCE); @@ -1297,8 +1299,8 @@ static JSValue js_structured_clone(JSContext *ctx, JSValueConst this_val, static JSClassID js_hash_state_class_id; typedef struct { - crypto_hash_sha512_state h; - int finalized; + crypto_hash_sha512_state h; + int finalized; } TART_HashState; @@ -1317,53 +1319,53 @@ static JSClassDef js_hash_state_class = { static JSValue js_talercrypto_hash_state_init(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - TART_HashState *hstate; - JSValue obj; + TART_HashState *hstate; + JSValue obj; - hstate = js_malloc_rt(JS_GetRuntime(ctx), sizeof (TART_HashState)); - if (!hstate) { - obj = JS_EXCEPTION; - goto done; - } - hstate->finalized = FALSE; - obj = JS_NewObjectClass(ctx, js_hash_state_class_id); - crypto_hash_sha512_init(&hstate->h); - JS_SetOpaque(obj, hstate); - hstate = NULL; - return obj; + hstate = js_malloc_rt(JS_GetRuntime(ctx), sizeof (TART_HashState)); + if (!hstate) { + obj = JS_EXCEPTION; + goto done; + } + hstate->finalized = FALSE; + obj = JS_NewObjectClass(ctx, js_hash_state_class_id); + crypto_hash_sha512_init(&hstate->h); + JS_SetOpaque(obj, hstate); + hstate = NULL; + return obj; done: - if (NULL != hstate) { - js_free_rt(JS_GetRuntime(ctx), hstate); - } - return obj; + if (NULL != hstate) { + js_free_rt(JS_GetRuntime(ctx), hstate); + } + return obj; } static JSValue js_talercrypto_hash_state_update(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - JSValue state = argv[0]; - JSValue data_val = argv[1]; - TART_HashState *hstate; - uint8_t *data; - size_t data_len; + JSValue state = argv[0]; + JSValue data_val = argv[1]; + TART_HashState *hstate; + uint8_t *data; + size_t data_len; - hstate = JS_GetOpaque(state, js_hash_state_class_id); + hstate = JS_GetOpaque(state, js_hash_state_class_id); - if (!hstate) { - return JS_ThrowTypeError(ctx, "expected HashState"); - } + if (!hstate) { + return JS_ThrowTypeError(ctx, "expected HashState"); + } - if (hstate->finalized) { - return JS_ThrowTypeError(ctx, "already finalized"); - } + if (hstate->finalized) { + return JS_ThrowTypeError(ctx, "already finalized"); + } - data = JS_GetArrayBuffer(ctx, &data_len, data_val); + data = JS_GetArrayBuffer(ctx, &data_len, data_val); - if (0 != crypto_hash_sha512_update(&hstate->h, data, data_len)) { - return JS_ThrowInternalError(ctx, "hashing failed"); - } + if (0 != crypto_hash_sha512_update(&hstate->h, data, data_len)) { + return JS_ThrowInternalError(ctx, "hashing failed"); + } - return JS_UNDEFINED; + return JS_UNDEFINED; } static JSValue js_talercrypto_hash_state_finish(JSContext *ctx, JSValue this_val, @@ -1627,75 +1629,75 @@ done: static JSValue js_sqlite3_close(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - JSValue db_handle = argv[0]; - sqlite3 *sqlite3_db; + JSValue db_handle = argv[0]; + sqlite3 *sqlite3_db; - sqlite3_db = JS_GetOpaque(db_handle, js_sqlite3_database_class_id); + sqlite3_db = JS_GetOpaque(db_handle, js_sqlite3_database_class_id); - if (!sqlite3_db) { - return JS_ThrowTypeError(ctx, "invalid sqlite3 database handle"); - } + if (!sqlite3_db) { + return JS_ThrowTypeError(ctx, "invalid sqlite3 database handle"); + } - (void) sqlite3_close_v2(sqlite3_db); - JS_SetOpaque(db_handle, NULL); - return JS_UNDEFINED; + (void) sqlite3_close_v2(sqlite3_db); + JS_SetOpaque(db_handle, NULL); + return JS_UNDEFINED; } // (handle: Sqlite3Database, stmt: string) => Sqlite3Statement static JSValue js_sqlite3_prepare(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - JSValue db_handle = argv[0]; - JSValue stmt_str = argv[1]; - JSValue ret_val = JS_UNDEFINED; - JSValue stmt_obj = JS_UNDEFINED; - int ret; - sqlite3 *sqlite3_db; - sqlite3_stmt *stmt; - const char *stmt_cstr; - const char *tail; + JSValue db_handle = argv[0]; + JSValue stmt_str = argv[1]; + JSValue ret_val = JS_UNDEFINED; + JSValue stmt_obj = JS_UNDEFINED; + int ret; + sqlite3 *sqlite3_db; + sqlite3_stmt *stmt; + const char *stmt_cstr; + const char *tail; - sqlite3_db = JS_GetOpaque(db_handle, js_sqlite3_database_class_id); + sqlite3_db = JS_GetOpaque(db_handle, js_sqlite3_database_class_id); - if (!sqlite3_db) { - return JS_ThrowTypeError(ctx, "invalid sqlite3 database handle"); - } + if (!sqlite3_db) { + return JS_ThrowTypeError(ctx, "invalid sqlite3 database handle"); + } - stmt_cstr = JS_ToCString(ctx, stmt_str); + stmt_cstr = JS_ToCString(ctx, stmt_str); - if (!stmt_cstr) { - ret_val = JS_ThrowTypeError(ctx, "invalid prepared statement, string expected"); - goto done; - } + if (!stmt_cstr) { + ret_val = JS_ThrowTypeError(ctx, "invalid prepared statement, string expected"); + goto done; + } - ret = sqlite3_prepare_v3(sqlite3_db, stmt_cstr, (int) strlen(stmt_cstr), 0, &stmt, &tail); - if (SQLITE_OK != ret) { - ret_val = JS_ThrowTypeError(ctx, "unable to prepare"); - goto done; - } + ret = sqlite3_prepare_v3(sqlite3_db, stmt_cstr, (int) strlen(stmt_cstr), 0, &stmt, &tail); + if (SQLITE_OK != ret) { + ret_val = JS_ThrowTypeError(ctx, "unable to prepare"); + goto done; + } - stmt_obj = JS_NewObjectClass(ctx, js_sqlite3_statement_class_id); - JS_SetOpaque(stmt_obj, stmt); - ret_val = stmt_obj; + stmt_obj = JS_NewObjectClass(ctx, js_sqlite3_statement_class_id); + JS_SetOpaque(stmt_obj, stmt); + ret_val = stmt_obj; done: - JS_FreeCString(ctx, stmt_cstr); - return ret_val; + JS_FreeCString(ctx, stmt_cstr); + return ret_val; } static JSValue js_sqlite3_finalize(JSContext *ctx, JSValue this_val, int argc, JSValueConst *argv) { - sqlite3_stmt *stmt; - - stmt = JS_GetOpaque(argv[0], js_sqlite3_statement_class_id); - if (!stmt) { - return JS_ThrowTypeError(ctx, "unable to finalize (not a statement)"); - } - // FIXME: Check error code and warn? - sqlite3_finalize(stmt); - JS_SetOpaque(argv[0], NULL); - return JS_UNDEFINED; + sqlite3_stmt *stmt; + + stmt = JS_GetOpaque(argv[0], js_sqlite3_statement_class_id); + if (!stmt) { + return JS_ThrowTypeError(ctx, "unable to finalize (not a statement)"); + } + // FIXME: Check error code and warn? + sqlite3_finalize(stmt); + JS_SetOpaque(argv[0], NULL); + return JS_UNDEFINED; } static int sql_exec_cb(void *cls, int numcol, char **res, char **colnames) { @@ -2151,8 +2153,9 @@ JSModuleDef *tart_init_module_talercrypto(JSContext *ctx, const char *module_nam { JSModuleDef *m; m = JS_NewCModule(ctx, module_name, tart_talercrypto_init); - if (!m) + if (!m) { return NULL; + } JS_AddModuleExportList(ctx, m, tart_talercrypto_funcs, countof(tart_talercrypto_funcs)); return m;