pwhash: don't enforce the same limits for argon2i and argon2id
Fixes #606 Also, keep enforcing a minimum number of iterations to create argon2i hashes, but relax that restriction for verification, as it can be useful to migrate from hashes made using other libraries.
This commit is contained in:
parent
a8ebd37b7b
commit
d49d7e8d4f
@ -47,7 +47,7 @@
|
||||
ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
|
||||
|
||||
/* Minimum and maximum number of passes */
|
||||
#define ARGON2_MIN_TIME UINT32_C(3)
|
||||
#define ARGON2_MIN_TIME UINT32_C(1)
|
||||
#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Minimum and maximum password length in bytes */
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "crypto_pwhash.h"
|
||||
#include "crypto_pwhash_argon2i.h"
|
||||
#include "crypto_pwhash_argon2id.h"
|
||||
#include "private/common.h"
|
||||
#include "randombytes.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -26,30 +27,36 @@ crypto_pwhash_argon2i_alg_argon2i13(void)
|
||||
size_t
|
||||
crypto_pwhash_argon2i_bytes_min(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MIN >= ARGON2_MIN_OUTLEN);
|
||||
return crypto_pwhash_argon2i_BYTES_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_bytes_max(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MAX <= ARGON2_MAX_OUTLEN);
|
||||
return crypto_pwhash_argon2i_BYTES_MAX;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_passwd_min(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH);
|
||||
return crypto_pwhash_argon2i_PASSWD_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_passwd_max(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH);
|
||||
return crypto_pwhash_argon2i_PASSWD_MAX;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_saltbytes(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES >= ARGON2_MIN_SALT_LENGTH);
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES <= ARGON2_MAX_SALT_LENGTH);
|
||||
return crypto_pwhash_argon2i_SALTBYTES;
|
||||
}
|
||||
|
||||
@ -68,24 +75,28 @@ crypto_pwhash_argon2i_strprefix(void)
|
||||
size_t
|
||||
crypto_pwhash_argon2i_opslimit_min(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME);
|
||||
return crypto_pwhash_argon2i_OPSLIMIT_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_opslimit_max(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME);
|
||||
return crypto_pwhash_argon2i_OPSLIMIT_MAX;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_memlimit_min(void)
|
||||
{
|
||||
COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY);
|
||||
return crypto_pwhash_argon2i_MEMLIMIT_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2i_memlimit_max(void)
|
||||
{
|
||||
COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY);
|
||||
return crypto_pwhash_argon2i_MEMLIMIT_MAX;
|
||||
}
|
||||
|
||||
@ -132,20 +143,29 @@ crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen,
|
||||
unsigned long long opslimit, size_t memlimit, int alg)
|
||||
{
|
||||
memset(out, 0, outlen);
|
||||
memlimit /= 1024U;
|
||||
if (outlen > ARGON2_MAX_OUTLEN || passwdlen > ARGON2_MAX_PWD_LENGTH ||
|
||||
opslimit > ARGON2_MAX_TIME || memlimit > ARGON2_MAX_MEMORY) {
|
||||
if (outlen > crypto_pwhash_argon2i_BYTES_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (outlen < ARGON2_MIN_OUTLEN || passwdlen < ARGON2_MIN_PWD_LENGTH ||
|
||||
opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) {
|
||||
if (outlen < crypto_pwhash_argon2i_BYTES_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
|
||||
opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
|
||||
memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
|
||||
opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN ||
|
||||
memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13:
|
||||
if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) memlimit,
|
||||
if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen, salt,
|
||||
(size_t) crypto_pwhash_argon2i_SALTBYTES, out,
|
||||
(size_t) outlen) != ARGON2_OK) {
|
||||
@ -167,19 +187,20 @@ crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
|
||||
unsigned char salt[crypto_pwhash_argon2i_SALTBYTES];
|
||||
|
||||
memset(out, 0, crypto_pwhash_argon2i_STRBYTES);
|
||||
memlimit /= 1024U;
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH || opslimit > ARGON2_MAX_TIME ||
|
||||
memlimit > ARGON2_MAX_MEMORY) {
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
|
||||
opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
|
||||
memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH || opslimit < ARGON2_MIN_TIME ||
|
||||
memlimit < ARGON2_MIN_MEMORY) {
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
|
||||
opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN ||
|
||||
memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
randombytes_buf(salt, sizeof salt);
|
||||
if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit,
|
||||
if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen, salt,
|
||||
sizeof salt, STR_HASHBYTES, out,
|
||||
crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) {
|
||||
@ -195,12 +216,12 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES],
|
||||
{
|
||||
int verify_ret;
|
||||
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
/* LCOV_EXCL_START */
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH) {
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "argon2-core.h"
|
||||
#include "argon2.h"
|
||||
#include "crypto_pwhash_argon2id.h"
|
||||
#include "private/common.h"
|
||||
#include "randombytes.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -22,30 +23,36 @@ crypto_pwhash_argon2id_alg_argon2id13(void)
|
||||
size_t
|
||||
crypto_pwhash_argon2id_bytes_min(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MIN >= ARGON2_MIN_OUTLEN);
|
||||
return crypto_pwhash_argon2id_BYTES_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_bytes_max(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MAX <= ARGON2_MAX_OUTLEN);
|
||||
return crypto_pwhash_argon2id_BYTES_MAX;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_passwd_min(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH);
|
||||
return crypto_pwhash_argon2id_PASSWD_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_passwd_max(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH);
|
||||
return crypto_pwhash_argon2id_PASSWD_MAX;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_saltbytes(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES >= ARGON2_MIN_SALT_LENGTH);
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES <= ARGON2_MAX_SALT_LENGTH);
|
||||
return crypto_pwhash_argon2id_SALTBYTES;
|
||||
}
|
||||
|
||||
@ -64,24 +71,28 @@ crypto_pwhash_argon2id_strprefix(void)
|
||||
size_t
|
||||
crypto_pwhash_argon2id_opslimit_min(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MIN >= ARGON2_MIN_TIME);
|
||||
return crypto_pwhash_argon2id_OPSLIMIT_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_opslimit_max(void)
|
||||
{
|
||||
COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MAX <= ARGON2_MAX_TIME);
|
||||
return crypto_pwhash_argon2id_OPSLIMIT_MAX;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_memlimit_min(void)
|
||||
{
|
||||
COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY);
|
||||
return crypto_pwhash_argon2id_MEMLIMIT_MIN;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_pwhash_argon2id_memlimit_max(void)
|
||||
{
|
||||
COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY);
|
||||
return crypto_pwhash_argon2id_MEMLIMIT_MAX;
|
||||
}
|
||||
|
||||
@ -128,20 +139,29 @@ crypto_pwhash_argon2id(unsigned char *const out, unsigned long long outlen,
|
||||
unsigned long long opslimit, size_t memlimit, int alg)
|
||||
{
|
||||
memset(out, 0, outlen);
|
||||
memlimit /= 1024U;
|
||||
if (outlen > ARGON2_MAX_OUTLEN || passwdlen > ARGON2_MAX_PWD_LENGTH ||
|
||||
opslimit > ARGON2_MAX_TIME || memlimit > ARGON2_MAX_MEMORY) {
|
||||
if (outlen > crypto_pwhash_argon2id_BYTES_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (outlen < ARGON2_MIN_OUTLEN || passwdlen < ARGON2_MIN_PWD_LENGTH ||
|
||||
opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) {
|
||||
if (outlen < crypto_pwhash_argon2id_BYTES_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
|
||||
opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
|
||||
memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
|
||||
opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN ||
|
||||
memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
|
||||
if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) memlimit,
|
||||
if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen, salt,
|
||||
(size_t) crypto_pwhash_argon2id_SALTBYTES, out,
|
||||
(size_t) outlen) != ARGON2_OK) {
|
||||
@ -163,19 +183,20 @@ crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES],
|
||||
unsigned char salt[crypto_pwhash_argon2id_SALTBYTES];
|
||||
|
||||
memset(out, 0, crypto_pwhash_argon2id_STRBYTES);
|
||||
memlimit /= 1024U;
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH || opslimit > ARGON2_MAX_TIME ||
|
||||
memlimit > ARGON2_MAX_MEMORY) {
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
|
||||
opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
|
||||
memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH || opslimit < ARGON2_MIN_TIME ||
|
||||
memlimit < ARGON2_MIN_MEMORY) {
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
|
||||
opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN ||
|
||||
memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
randombytes_buf(salt, sizeof salt);
|
||||
if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit,
|
||||
if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U),
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen, salt,
|
||||
sizeof salt, STR_HASHBYTES, out,
|
||||
crypto_pwhash_argon2id_STRBYTES) != ARGON2_OK) {
|
||||
@ -191,12 +212,12 @@ crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES
|
||||
{
|
||||
int verify_ret;
|
||||
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
/* LCOV_EXCL_START */
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH) {
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -8,5 +8,4 @@ c121209f0ba70aed93d49200e5dc82cce013cef25ea31e160bf8db3cf448a59d1a56f6c19259e18e
|
||||
e942951dfbc2d508294b10f9e97b47d0cd04e668a043cb95679cc1139df7c27cd54367688725be9d069f5704c12223e7e4ca181fbd0bed18bb4634795e545a6c04a7306933a41a794baedbb628d41bc285e0b9084055ae136f6b63624c874f5a1e1d8be7b0b7227a171d2d7ed578d88bfdcf18323198962d0dcad4126fd3f21adeb1e11d66252ea0c58c91696e91031bfdcc2a9dc0e028d17b9705ba2d7bcdcd1e3ba75b4b1fea
|
||||
9fbbc02a420b00614a49a8e8d89834df368fa54dbef5dce7f9928f4d09f45ce22766598c0c979a707b1df130ab8d63802447923f6e8b89b3c183d71d694161569b1937d8b58f0091fcb8b1f48f2e3f43067bb2498b727fb62cc776ed39219613aa2083619385ec64dfb38f3cda7fddce9cec708a1aa5e9b09d6a5f063cda6c644c5e4a6c1bba9362b27f050984ee3a91bbed69160c95d63c04724f
|
||||
28645e1a4f5bc2a58786c87f0d88c2c68047b874b122e2c3936fb6adf26d7ca8fbcb872a8aef282ff202526a91b8ca1d0926c4ae0f5429c342bfd4987916b147ccaa1624bbb2d3f197e56601a541939a1a867ee659515d379d252c8b53aa2297b6008f97bc4a246040b0fb4f46754482884ff04bdade7ffc74989c68ec085de660ef2071db22bacc227d43af282a2336049d78fe0b8ff543628dc8
|
||||
[tv3] pwhash_str failure (maybe intentional): [0]
|
||||
OK
|
||||
|
@ -293,8 +293,13 @@ main(void)
|
||||
return 1;
|
||||
}
|
||||
if (crypto_pwhash_argon2id_str(str_out2, passwd, strlen(passwd), 1, MEMLIMIT) !=
|
||||
0) {
|
||||
printf("pwhash_argon2id_str() with a small opslimit should not have failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (crypto_pwhash_argon2id_str(str_out2, passwd, strlen(passwd), 0, MEMLIMIT) !=
|
||||
-1) {
|
||||
printf("pwhash_argon2id_str() with a small opslimit should have failed\n");
|
||||
printf("pwhash_argon2id_str() with a null opslimit should have failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (crypto_pwhash_argon2id_str_verify("$argon2id$m=65536,t=2,p=1c29tZXNhbHQ"
|
||||
|
@ -4,7 +4,7 @@
|
||||
[tv] pwhash failure (maybe intentional): [3]
|
||||
08d8cd330c57e1b4643241d05bb468ba4ee4e932cd0858816be9ef15360b27bbd06a87130ee92222be267a29b81f5ae8fe8613324cfc4832dc49387fd0602f1c57b4d0f3855db94fb7e12eb05f9a484aed4a4307abf586cd3d55c809bc081541e00b682772fb2066504ff935b8ebc551a2083882f874bc0fae68e56848ae34c91097c3bf0cca8e75c0797eef3efde3f75e005815018db3cf7c109a812264c4de69dcb22322dbbcfa447f5b00ecd1b04a7be1569c8e556adb7bba48adf81d
|
||||
d6e9d6cabd42fb9ba7162fe9b8e41d59d3c7034756cb460c9affe393308bd0225ce0371f2e6c3ca32aca2002bf2d3909c6b6e7dfc4a00e850ff4f570f8f749d4bb6f0091e554be67a9095ae1eefaa1a933316cbec3c2fd4a14a5b6941bda9b7eabd821d79abde2475a53af1a8571c7ee46460be415882e0b393f48c12f740a6a72cba9773000602e13b40d3dfa6ac1d4ec43a838b7e3e165fecad4b2498389e60a3ff9f0f8f4b9fca1126e64f49501e38690
|
||||
[tv] pwhash failure (maybe intentional): [6]
|
||||
7fb72409b0987f8190c3729710e98c3f80c5a8727d425fdcde7f3644d467fe973f5b5fee683bd3fce812cb9ae5e9921a2d06c2f1905e4e839692f2b934b682f11a2fe2b90482ea5dd234863516dba6f52dc0702d324ec77d860c2e181f84472bd7104fedce071ffa93c5309494ad51623d214447a7b2b1462dc7d5d55a1f6fd5b54ce024118d86f0c6489d16545aaa87b6689dad9f2fb47fda9894f8e12b87d978b483ccd4cc5fd9595cdc7a818452f915ce2f7df95ec12b1c72e3788d473441d884f9748eb14703c21b45d82fd667b85f5b2d98c13303b3fe76285531a826b6fc0fe8e3dddecf
|
||||
4e702bc5f891df884c6ddaa243aa846ce3c087fe930fef0f36b3c2be34164ccc295db509254743f18f947159c813bcd5dd8d94a3aec93bbe57605d1fad1aef1112687c3d4ef1cb329d21f1632f626818d766915d886e8d819e4b0b9c9307f4b6afc081e13b0cf31db382ff1bf05a16aac7af696336d75e99f82163e0f371e1d25c4add808e215697ad3f779a51a462f8bf52610af21fc69dba6b072606f2dabca7d4ae1d91d919
|
||||
2d232f9dc4de96628b2a4c2b39ceb6a813011fb74a3ba1da096761fabe08f563bd91366aba5c5e35aecd98643cabc16ce560dca261a963230a1fa2af52f2413a57a827c6ee13bcec0c123d195914a55700ccb5756196a86fb9cb4aeacccc0e6dd850f4386b705aaae147ea347543b7fbe24553d9da41f1b335b6e9980cdb966cf7b48520eb42a7269380c885dbefbccf447851fcacbe1753a5b9e1
|
||||
34b207147fb7ef83e1ca1a97e30aa6e08ea9b6b1048c59c9c13050dff33e76ce3c440d7f018f817e6b8593e78f339ba633b9d7ec3519b5eafbcc4bc2d20b5136bbc7e5b7e92ff37d024bbbecf5738f718ab22c8adcdb82ceffc233b8ad61f91850abdfe8bb119775d9c4243ec1ac761dfbd132489228dfeab5268c7f0ddc29f56b957d1b76c874cdd77e16139e0df9b847248fd782c9a1147b8480
|
||||
|
Loading…
Reference in New Issue
Block a user