CVE-2023-36327 (published 2023-09-01T16:15Z)

Integer Overflow vulnerability in RELIC before commit 421f2e91cf2ba42473d4d54daf24e295679e290e, allows attackers to execute arbitrary code and cause a denial of service in pos argument in bn_get_prime function.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-190
cwe_name: Integer Overflow or Wraparound
description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
extended_description: 
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/relic-toolkit/relic
commit_details: repo_url: https://github.com/relic-toolkit/relic
author: Diego F. Aranha
author_date: 2022-11-14 15:04:06+01:00
msg: Remove dangerous API for returning small primes from an internal table.
repository: repo_url: https://github.com/relic-toolkit/relic
repo_name: relic-toolkit/relic
description: Code
repo_language: C
owner: relic-toolkit
file_changes: filename: relic_bn.h
change_type: ModificationType.MODIFY
diff: @@ -1270,15 +1270,6 @@ int bn_smb_leg(const bn_t a, const bn_t b);
  */
 int bn_smb_jac(const bn_t a, const bn_t b);
 
-/**
- * Returns a small precomputed prime from a given position in the list of prime
- * numbers.
- *
- * @param[in] pos			- the position in the prime sequence.
- * @return a prime if the position is lower than 512, 0 otherwise.
- */
-dig_t bn_get_prime(int pos);
-
 /**
  * Tests if a number is a probable prime.
  *

programming_language: C
filename: relic_label.h
change_type: ModificationType.MODIFY
diff: @@ -264,7 +264,6 @@
 #undef bn_lcm
 #undef bn_smb_leg
 #undef bn_smb_jac
-#undef bn_get_prime
 #undef bn_is_prime
 #undef bn_is_prime_basic
 #undef bn_is_prime_rabin
@@ -373,7 +372,6 @@
 #define bn_lcm 	RLC_PREFIX(bn_lcm)
 #define bn_smb_leg 	RLC_PREFIX(bn_smb_leg)
 #define bn_smb_jac 	RLC_PREFIX(bn_smb_jac)
-#define bn_get_prime 	RLC_PREFIX(bn_get_prime)
 #define bn_is_prime 	RLC_PREFIX(bn_is_prime)
 #define bn_is_prime_basic 	RLC_PREFIX(bn_is_prime_basic)
 #define bn_is_prime_rabin 	RLC_PREFIX(bn_is_prime_rabin)

programming_language: Ruby
filename: relic_bn_prime.c
change_type: ModificationType.MODIFY
diff: @@ -170,13 +170,6 @@ static void bn_exp(bn_t c, const bn_t a, const bn_t b, const bn_t m) {
 /* Public definitions                                                         */
 /*============================================================================*/
 
-dig_t bn_get_prime(int pos) {
-	if (pos >= BASIC_TESTS) {
-		return 0;
-	}
-	return primes[pos];
-}
-
 int bn_is_prime(const bn_t a) {
 	int result;
 

programming_language: C
filename: test_cp.c
change_type: ModificationType.MODIFY
diff: @@ -132,6 +132,7 @@ static int benaloh(void) {
 	uint8_t buf[RLC_BN_BITS / 8 + 1];
 	size_t len;
 	int result;
+	dig_t prime = 0xFB;
 
 	bn_null(a);
 	bn_null(b);
@@ -144,13 +145,13 @@ static int benaloh(void) {
 		bdpe_new(pub);
 		bdpe_new(prv);
 
-		result = cp_bdpe_gen(pub, prv, bn_get_prime(47), RLC_BN_BITS);
+		result = cp_bdpe_gen(pub, prv, prime, RLC_BN_BITS);
 
 		TEST_CASE("benaloh encryption/decryption is correct") {
 			TEST_ASSERT(result == RLC_OK, end);
 			len = RLC_BN_BITS / 8 + 1;
 			rand_bytes(buf, 1);
-			in = buf[0] % bn_get_prime(47);
+			in = buf[0] % prime;
 			TEST_ASSERT(cp_bdpe_enc(buf, &len, in, pub) == RLC_OK, end);
 			TEST_ASSERT(cp_bdpe_dec(&out, buf, len, prv) == RLC_OK, end);
 			TEST_ASSERT(in == out, end);
@@ -160,12 +161,12 @@ static int benaloh(void) {
 			TEST_ASSERT(result == RLC_OK, end);
 			len = RLC_BN_BITS / 8 + 1;
 			rand_bytes(buf, 1);
-			in = buf[0] % bn_get_prime(47);
+			in = buf[0] % prime;
 			TEST_ASSERT(cp_bdpe_enc(buf, &len, in, pub) == RLC_OK, end);
 			bn_read_bin(a, buf, len);
 			rand_bytes(buf, 1);
-			out = (buf[0] % bn_get_prime(47));
-			in = (in + out) % bn_get_prime(47);
+			out = (buf[0] % prime);
+			in = (in + out) % prime;
 			TEST_ASSERT(cp_bdpe_enc(buf, &len, out, pub) == RLC_OK, end);
 			bn_read_bin(b, buf, len);
 			bn_mul(a, a, b);
@@ -2237,26 +2238,28 @@ static int psi(void) {
 			}
 		} TEST_END;
 
-		TEST_CASE("pairing-based laconic private set intersection is correct") {
-			pc_get_ord(q);
-			for (int j = 0; j < M; j++) {
-				bn_rand_mod(x[j], q);
-			}
-			for (int j = 0; j < N; j++) {
-				bn_rand_mod(y[j], q);
-			}
-			TEST_ASSERT(cp_pbpsi_gen(q, ss, s, M) == RLC_OK, end);
-			TEST_ASSERT(cp_pbpsi_ask(d, r, x, s, M) == RLC_OK, end);
-			for (int k = 0; k <= N; k++) {
-				for (int j = 0; j < k; j++) {
-					bn_copy(y[j], x[j]);
+		if (pc_param_set_any() == RLC_OK) {
+			TEST_CASE("pairing-based laconic private set intersection is correct") {
+				pc_get_ord(q);
+				for (int j = 0; j < M; j++) {
+					bn_rand_mod(x[j], q);
 				}
-				TEST_ASSERT(cp_pbpsi_ans(t, u, ss, d[0], y, N) == RLC_OK, end);
-				TEST_ASSERT(cp_pbpsi_int(z, &l, d, x, M, t, u, N) == RLC_OK,
-					end);
-				TEST_ASSERT(l == k, end);
-			}
-		} TEST_END;
+				for (int j = 0; j < N; j++) {
+					bn_rand_mod(y[j], q);
+				}
+				TEST_ASSERT(cp_pbpsi_gen(q, ss, s, M) == RLC_OK, end);
+				TEST_ASSERT(cp_pbpsi_ask(d, r, x, s, M) == RLC_OK, end);
+				for (int k = 0; k <= N; k++) {
+					for (int j = 0; j < k; j++) {
+						bn_copy(y[j], x[j]);
+					}
+					TEST_ASSERT(cp_pbpsi_ans(t, u, ss, d[0], y, N) == RLC_OK, end);
+					TEST_ASSERT(cp_pbpsi_int(z, &l, d, x, M, t, u, N) == RLC_OK,
+						end);
+					TEST_ASSERT(l == k, end);
+				}
+			} TEST_END;
+		}
 	}
 	RLC_CATCH_ANY {
 		RLC_ERROR(end);
@@ -2298,16 +2301,6 @@ int main(void) {
 
 	util_banner("Tests for the CP module", 0);
 
-	#if defined(WITH_BN) && defined(WITH_PC)
-		util_banner("Protocols based on accumulators:\n", 0);
-		if (pc_param_set_any() == RLC_OK) {
-			if (psi() != RLC_OK) {
-				core_clean();
-				return 1;
-			}
-		}
-	#endif
-
 #if defined(WITH_BN)
 	util_banner("Protocols based on integer factorization:\n", 0);
 	if (rsa() != RLC_OK) {
@@ -2466,6 +2459,14 @@ int main(void) {
 	}
 #endif
 
+#if defined(WITH_BN) && defined(WITH_PC)
+	util_banner("Protocols based on accumulators:\n", 0);
+	if (psi() != RLC_OK) {
+		core_clean();
+		return 1;
+	}
+#endif
+
 	util_banner("All tests have passed.\n", 0);
 
 	core_clean();

programming_language: C