mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 15:30:49 +02:00
ML-KEM Wconversion fixes
* fix -Wconversion warnings * allow APIs without RNG usage in case WC_NO_RNG is defined
This commit is contained in:
@@ -18,12 +18,17 @@ jobs:
|
||||
matrix:
|
||||
config: [
|
||||
# Add new configs here
|
||||
'--disable-asm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-smallstack --disable-asm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-smallstack --enable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
|
||||
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests CPPFLAGS="-Wdeclaration-after-statement -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion" --enable-32bit CFLAGS=-m32'
|
||||
'--disable-asm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-smallstack --disable-asm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-smallstack --enable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion"',
|
||||
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
|
||||
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wdeclaration-after-statement -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion" --enable-32bit CFLAGS=-m32',
|
||||
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes,small CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
|
||||
'--enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes,no-large-code CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
|
||||
'--enable-smallstack --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
|
||||
'--disable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem CPPFLAGS="-DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -Wdeclaration-after-statement -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion" --enable-32bit CFLAGS=-m32',
|
||||
'--disable-intelasm --enable-cryptonly --enable-all-crypto --disable-examples --disable-benchmark --disable-crypttests --enable-mlkem=yes,small CPPFLAGS="-DWOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM -DWOLFSSL_MLKEM_MAKEKEY_SMALL_MEM -Wconversion -Warith-conversion -Wenum-conversion -Wfloat-conversion -Wsign-conversion -DNO_INT128"',
|
||||
]
|
||||
name: build library
|
||||
if: github.repository_owner == 'wolfssl'
|
||||
|
||||
@@ -1746,6 +1746,9 @@ do
|
||||
small)
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MLKEM_SMALL"
|
||||
;;
|
||||
no-large-code)
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MLKEM_NO_LARGE_CODE"
|
||||
;;
|
||||
cache-a)
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MLKEM_CACHE_A"
|
||||
;;
|
||||
|
||||
+31
-17
@@ -367,6 +367,7 @@ int wc_MlKemKey_Free(MlKemKey* key)
|
||||
*/
|
||||
int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng)
|
||||
{
|
||||
#ifndef WC_NO_RNG
|
||||
int ret = 0;
|
||||
unsigned char rand[WC_ML_KEM_MAKEKEY_RAND_SZ];
|
||||
|
||||
@@ -396,6 +397,11 @@ int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng)
|
||||
|
||||
/* Step 4: return ret != 0 on falsum or internal key generation failure. */
|
||||
return ret;
|
||||
#else
|
||||
(void)key;
|
||||
(void)rng;
|
||||
return NOT_COMPILED_IN;
|
||||
#endif /* WC_NO_RNG */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,16 +525,16 @@ int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand,
|
||||
#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM
|
||||
#ifndef WOLFSSL_MLKEM_CACHE_A
|
||||
/* e (v) | a (m) */
|
||||
e = (sword16*)XMALLOC((k + 1) * k * MLKEM_N * sizeof(sword16),
|
||||
e = (sword16*)XMALLOC((size_t)((k + 1) * k * MLKEM_N) * sizeof(sword16),
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#else
|
||||
/* e (v) */
|
||||
e = (sword16*)XMALLOC(k * MLKEM_N * sizeof(sword16),
|
||||
e = (sword16*)XMALLOC((size_t)(k * MLKEM_N) * sizeof(sword16),
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
#else
|
||||
/* e (v) */
|
||||
e = (sword16*)XMALLOC(k * MLKEM_N * sizeof(sword16),
|
||||
e = (sword16*)XMALLOC((size_t)(k * MLKEM_N) * sizeof(sword16),
|
||||
key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
if (e == NULL) {
|
||||
@@ -560,7 +566,7 @@ int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand,
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_ML_KEM
|
||||
{
|
||||
buf[0] = k;
|
||||
buf[0] = (byte)k;
|
||||
/* Expand 33 bytes of random to 64.
|
||||
* Alg 13: Step 1: (rho,sigma) <- G(d||k)
|
||||
*/
|
||||
@@ -871,7 +877,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
|
||||
/* Generate noise using PRF.
|
||||
* Steps 9-17: generate y, e_1, e_2
|
||||
*/
|
||||
ret = mlkem_get_noise(&key->prf, k, y, e1, e2, r);
|
||||
ret = mlkem_get_noise(&key->prf, (int)k, y, e1, e2, r);
|
||||
}
|
||||
#ifdef WOLFSSL_MLKEM_CACHE_A
|
||||
if ((ret == 0) && ((key->flags & MLKEM_FLAG_A_SET) != 0)) {
|
||||
@@ -892,7 +898,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
|
||||
if (ret == 0) {
|
||||
/* Generate the transposed matrix.
|
||||
* Step 4-8: generate matrix A_hat */
|
||||
ret = mlkem_gen_matrix(&key->prf, a, k, key->pubSeed, 1);
|
||||
ret = mlkem_gen_matrix(&key->prf, a, (int)k, key->pubSeed, 1);
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Assign remaining allocated dynamic memory to pointers.
|
||||
@@ -902,7 +908,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
|
||||
|
||||
/* Perform encapsulation maths.
|
||||
* Steps 18-19, 21: calculate u and v */
|
||||
mlkem_encapsulate(key->pub, u, v, a, y, e1, e2, mu, k);
|
||||
mlkem_encapsulate(key->pub, u, v, a, y, e1, e2, mu, (int)k);
|
||||
}
|
||||
#else /* WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM */
|
||||
if (ret == 0) {
|
||||
@@ -914,7 +920,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
|
||||
mlkem_prf_init(&key->prf);
|
||||
/* Generate noise using PRF.
|
||||
* Steps 9-12: generate y */
|
||||
ret = mlkem_get_noise(&key->prf, k, y, NULL, NULL, r);
|
||||
ret = mlkem_get_noise(&key->prf, (int)k, y, NULL, NULL, r);
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Assign remaining allocated dynamic memory to pointers.
|
||||
@@ -925,7 +931,7 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
|
||||
/* Perform encapsulation maths.
|
||||
* Steps 13-17: generate e_1 and e_2
|
||||
* Steps 18-19, 21: calculate u and v */
|
||||
ret = mlkem_encapsulate_seeds(key->pub, &key->prf, u, a, y, k, m,
|
||||
ret = mlkem_encapsulate_seeds(key->pub, &key->prf, u, a, y, (int)k, m,
|
||||
key->pubSeed, r);
|
||||
}
|
||||
#endif /* WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM */
|
||||
@@ -1048,6 +1054,7 @@ static int wc_mlkemkey_check_h(MlKemKey* key)
|
||||
int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* c, unsigned char* k,
|
||||
WC_RNG* rng)
|
||||
{
|
||||
#ifndef WC_NO_RNG
|
||||
int ret = 0;
|
||||
unsigned char m[WC_ML_KEM_ENC_RAND_SZ];
|
||||
|
||||
@@ -1072,6 +1079,13 @@ int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* c, unsigned char* k,
|
||||
|
||||
/* Step 3: return ret != 0 on falsum or internal key generation failure. */
|
||||
return ret;
|
||||
#else
|
||||
(void)key;
|
||||
(void)c;
|
||||
(void)k;
|
||||
(void)rng;
|
||||
return NOT_COMPILED_IN;
|
||||
#endif /* WC_NO_RNG */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1382,7 +1396,7 @@ static MLKEM_NOINLINE int mlkemkey_decapsulate(MlKemKey* key, byte* m,
|
||||
|
||||
/* Decapsulate the cipher text into polynomial.
|
||||
* Step 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) */
|
||||
mlkem_decapsulate(key->priv, w, u, v, k);
|
||||
mlkem_decapsulate(key->priv, w, u, v, (int)k);
|
||||
|
||||
/* Convert the polynomial into a array of bytes (message).
|
||||
* Step 7: m <- ByteEncode_1(Compress_1(w)) */
|
||||
@@ -1540,7 +1554,7 @@ int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss,
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Compare generated cipher text with that passed in. */
|
||||
fail = mlkem_cmp(ct, cmp, ctSz);
|
||||
fail = mlkem_cmp(ct, cmp, (int)ctSz);
|
||||
|
||||
#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM)
|
||||
if (key->type & MLKEM_KYBER)
|
||||
@@ -1569,7 +1583,7 @@ int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss,
|
||||
if (ret == 0) {
|
||||
/* Set secret to kr or fake secret on comparison failure. */
|
||||
for (i = 0; i < WC_ML_KEM_SYM_SZ; i++) {
|
||||
ss[i] = kr[i] ^ ((kr[i] ^ msg[i]) & fail);
|
||||
ss[i] = (byte)(kr[i] ^ ((kr[i] ^ msg[i]) & fail));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1613,7 +1627,7 @@ static void mlkemkey_decode_public(sword16* pub, byte* pubSeed, const byte* p,
|
||||
|
||||
/* Decode public key that is vector of polynomials.
|
||||
* Step 2: t <- ByteDecode_12(ek_PKE[0 : 384k]) */
|
||||
mlkem_from_bytes(pub, p, k);
|
||||
mlkem_from_bytes(pub, p, (int)k);
|
||||
p += k * WC_ML_KEM_POLY_SIZE;
|
||||
|
||||
/* Read public key seed.
|
||||
@@ -1729,7 +1743,7 @@ int wc_MlKemKey_DecodePrivateKey(MlKemKey* key, const unsigned char* in,
|
||||
/* Decode private key that is vector of polynomials.
|
||||
* Alg 18 Step 1: dk_PKE <- dk[0 : 384k]
|
||||
* Alg 15 Step 5: s_hat <- ByteDecode_12(dk_PKE) */
|
||||
mlkem_from_bytes(key->priv, p, k);
|
||||
mlkem_from_bytes(key->priv, p, (int)k);
|
||||
p += k * WC_ML_KEM_POLY_SIZE;
|
||||
|
||||
/* Decode the public key that is after the private key. */
|
||||
@@ -1845,7 +1859,7 @@ int wc_MlKemKey_DecodePublicKey(MlKemKey* key, const unsigned char* in,
|
||||
|
||||
if (ret == 0) {
|
||||
mlkemkey_decode_public(key->pub, key->pubSeed, p, k);
|
||||
ret = mlkem_check_public(key->pub, k);
|
||||
ret = mlkem_check_public(key->pub, (int)k);
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Calculate public hash. */
|
||||
@@ -2090,7 +2104,7 @@ int wc_MlKemKey_EncodePrivateKey(MlKemKey* key, unsigned char* out, word32 len)
|
||||
|
||||
if (ret == 0) {
|
||||
/* Encode private key that is vector of polynomials. */
|
||||
mlkem_to_bytes(p, key->priv, k);
|
||||
mlkem_to_bytes(p, key->priv, (int)k);
|
||||
p += WC_ML_KEM_POLY_SIZE * k;
|
||||
|
||||
/* Encode public key. */
|
||||
@@ -2207,7 +2221,7 @@ int wc_MlKemKey_EncodePublicKey(MlKemKey* key, unsigned char* out, word32 len)
|
||||
int i;
|
||||
|
||||
/* Encode public key polynomial by polynomial. */
|
||||
mlkem_to_bytes(p, key->pub, k);
|
||||
mlkem_to_bytes(p, key->pub, (int)k);
|
||||
p += k * WC_ML_KEM_POLY_SIZE;
|
||||
|
||||
/* Append public seed. */
|
||||
|
||||
+406
-391
File diff suppressed because it is too large
Load Diff
+46
-3
@@ -46715,8 +46715,11 @@ out:
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
{
|
||||
wc_test_ret_t ret;
|
||||
WC_RNG rng;
|
||||
int i;
|
||||
#ifndef WC_NO_RNG
|
||||
WC_RNG rng;
|
||||
int rng_inited = 0;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
MlKemKey *key = NULL;
|
||||
#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
|
||||
@@ -46783,6 +46786,30 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#ifdef WC_NO_RNG
|
||||
#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
|
||||
/* Fake random data for testing (from mlkem768_kat) */
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte make_key_rand[] = {
|
||||
0x7c, 0x99, 0x35, 0xa0, 0xb0, 0x76, 0x94, 0xaa,
|
||||
0x0c, 0x6d, 0x10, 0xe4, 0xdb, 0x6b, 0x1a, 0xdd,
|
||||
0x2f, 0xd8, 0x1a, 0x25, 0xcc, 0xb1, 0x48, 0x03,
|
||||
0x2d, 0xcd, 0x73, 0x99, 0x36, 0x73, 0x7f, 0x2d,
|
||||
0x86, 0x26, 0xED, 0x79, 0xD4, 0x51, 0x14, 0x08,
|
||||
0x00, 0xE0, 0x3B, 0x59, 0xB9, 0x56, 0xF8, 0x21,
|
||||
0x0E, 0x55, 0x60, 0x67, 0x40, 0x7D, 0x13, 0xDC,
|
||||
0x90, 0xFA, 0x9E, 0x8B, 0x87, 0x2B, 0xFB, 0x8F
|
||||
};
|
||||
#ifndef WOLFSSL_MLKEM_NO_ENCAPSULATE
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte encap_rand[] = {
|
||||
0x14, 0x7c, 0x03, 0xf7, 0xa5, 0xbe, 0xbb, 0xa4,
|
||||
0x06, 0xc8, 0xfa, 0xe1, 0x87, 0x4d, 0x7f, 0x13,
|
||||
0xc8, 0x0e, 0xfe, 0x79, 0xa3, 0xa9, 0xa8, 0x74,
|
||||
0xcc, 0x09, 0xfe, 0x76, 0xf6, 0x99, 0x76, 0x15
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("mlkem_test");
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@@ -46826,6 +46853,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
#ifndef HAVE_FIPS
|
||||
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
|
||||
#else
|
||||
@@ -46833,6 +46861,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
#endif
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
rng_inited = 1;
|
||||
#endif /* WC_NO_RNG */
|
||||
|
||||
for (i = 0; i < (int)(sizeof(testData) / sizeof(*testData)); i++) {
|
||||
ret = wc_MlKemKey_Init(key, testData[i][0], HEAP_HINT, devId);
|
||||
@@ -46842,7 +46872,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
key_inited = 1;
|
||||
|
||||
#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
|
||||
#ifndef WC_NO_RNG
|
||||
ret = wc_MlKemKey_MakeKey(key, &rng);
|
||||
#else
|
||||
ret = wc_MlKemKey_MakeKeyWithRandom(key, make_key_rand,
|
||||
sizeof(make_key_rand));
|
||||
#endif
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
|
||||
|
||||
@@ -46863,7 +46898,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
|
||||
|
||||
#ifndef WOLFSSL_MLKEM_NO_ENCAPSULATE
|
||||
#ifndef WC_NO_RNG
|
||||
ret = wc_MlKemKey_Encapsulate(key, ct, ss, &rng);
|
||||
#else
|
||||
ret = wc_MlKemKey_EncapsulateWithRandom(key, ct, ss, encap_rand,
|
||||
sizeof(encap_rand));
|
||||
#endif
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_I(i), out);
|
||||
#endif
|
||||
@@ -46911,8 +46951,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
#ifdef WOLFSSL_WC_MLKEM
|
||||
#if !defined(WOLFSSL_NO_KYBER512) && !defined(WOLFSSL_NO_ML_KEM_512)
|
||||
ret = mlkem512_kat();
|
||||
@@ -46936,6 +46974,11 @@ out:
|
||||
if (key_inited)
|
||||
wc_MlKemKey_Free(key);
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
if (rng_inited)
|
||||
wc_FreeRng(&rng);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
|
||||
|
||||
Reference in New Issue
Block a user