commit f80e75edbecb86ddca12ffb61f48dde6cd13fa0a
parent 4ca4ac0bce6588bb565babbec41d32785b92d630
Author: Florian Dold <dold@taler.net>
Date: Sun, 9 Aug 2026 21:22:13 +0200
tart: bound attacker-controlled crypto work
Diffstat:
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/tart_module.c b/tart_module.c
@@ -38,6 +38,11 @@
static JSValue make_js_ta_copy(JSContext *ctx, uint8_t *data, size_t size);
+#define TART_MAX_RANDOM_BYTES (64U * 1024U * 1024U)
+#define TART_MAX_ARGON2_OUTPUT (64U * 1024U)
+#define TART_MAX_RSA_MODULUS_BYTES 1024U
+#define TART_MAX_RSA_EXPONENT_BYTES 8U
+
static JSValue js_encode_utf8(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
@@ -71,6 +76,9 @@ static JSValue js_random_bytes(JSContext *ctx, JSValueConst this_val,
if (0 != JS_ToUint32(ctx, &nbytes, argv[0])) {
return JS_EXCEPTION;
}
+ if (nbytes > TART_MAX_RANDOM_BYTES) {
+ return JS_ThrowRangeError(ctx, "random byte request is too large");
+ }
if (nbytes != 0) {
randbuf = js_malloc(ctx, nbytes);
if (!randbuf) {
@@ -93,7 +101,7 @@ static JSValue js_random_bytes(JSContext *ctx, JSValueConst this_val,
* @param a a character
* @return corresponding numeric value
*/
-static unsigned int
+static int
getValue__ (unsigned char a)
{
unsigned int dec;
@@ -272,6 +280,10 @@ static JSValue js_talercrypto_decode_crock(JSContext *ctx, JSValue this_val,
vbit = encoded_len % 5; /* padding! */
shift = 5 - vbit;
bits = (ret = getValue__ (enc[--rpos])) >> shift;
+ if (ret < 0 || (ret & ((1U << shift) - 1)) != 0) {
+ JS_ThrowTypeError(ctx, "invalid padding bits in encoding");
+ goto exception;
+ }
}
else
{
@@ -397,7 +409,9 @@ rsa_public_key_decode(RsaPub *pkey, uint8_t *inbuf, size_t inbuf_len)
memcpy(&encoded_len, p, sizeof encoded_len);
exp_len = ntohs(encoded_len);
sz = 4 + mod_len + exp_len;
- if (sz != inbuf_len || mod_len == 0 || exp_len == 0) {
+ if (sz != inbuf_len ||
+ mod_len < 128 || mod_len > TART_MAX_RSA_MODULUS_BYTES ||
+ exp_len == 0 || exp_len > TART_MAX_RSA_EXPONENT_BYTES) {
ret = -1;
goto cleanup;
}
@@ -557,12 +571,14 @@ static JSValue js_talercrypto_hash_argon2id(JSContext *ctx, JSValue this_val,
}
if (iters < crypto_pwhash_OPSLIMIT_MIN ||
- iters > crypto_pwhash_OPSLIMIT_MAX) {
+ iters > crypto_pwhash_OPSLIMIT_MAX ||
+ iters > crypto_pwhash_OPSLIMIT_MODERATE) {
JS_ThrowRangeError(ctx, "iterations out of range");
goto exception;
}
if (hash_len < crypto_pwhash_BYTES_MIN ||
- hash_len > crypto_pwhash_BYTES_MAX) {
+ hash_len > crypto_pwhash_BYTES_MAX ||
+ hash_len > TART_MAX_ARGON2_OUTPUT) {
JS_ThrowRangeError(ctx, "hash length out of range");
goto exception;
}
@@ -574,7 +590,8 @@ static JSValue js_talercrypto_hash_argon2id(JSContext *ctx, JSValue this_val,
}
if ((size_t) mem_size * 1024 < crypto_pwhash_MEMLIMIT_MIN ||
- (size_t) mem_size * 1024 > crypto_pwhash_MEMLIMIT_MAX) {
+ (size_t) mem_size * 1024 > crypto_pwhash_MEMLIMIT_MAX ||
+ (size_t) mem_size * 1024 > crypto_pwhash_MEMLIMIT_MODERATE) {
JS_ThrowRangeError(ctx, "memory size out of range");
goto exception;
}