mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 20:24:39 +02:00
SHA256, SHA384 and SHA512 error propagation. Minor impact on some of internal.c static functions.
This commit is contained in:
@@ -2696,8 +2696,19 @@ static int ConfirmSignature(const byte* buf, word32 bufSz,
|
|||||||
CYASSL_MSG("InitSha256 failed");
|
CYASSL_MSG("InitSha256 failed");
|
||||||
return 0; /* not confirmed */
|
return 0; /* not confirmed */
|
||||||
}
|
}
|
||||||
Sha256Update(&sha256, buf, bufSz);
|
|
||||||
Sha256Final(&sha256, digest);
|
ret = Sha256Update(&sha256, buf, bufSz);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Sha256Update failed");
|
||||||
|
return 0; /* not confirmed */
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = Sha256Final(&sha256, digest);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Sha256Final failed");
|
||||||
|
return 0; /* not confirmed */
|
||||||
|
}
|
||||||
|
|
||||||
typeH = SHA256h;
|
typeH = SHA256h;
|
||||||
digestSz = SHA256_DIGEST_SIZE;
|
digestSz = SHA256_DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
@@ -2713,8 +2724,19 @@ static int ConfirmSignature(const byte* buf, word32 bufSz,
|
|||||||
CYASSL_MSG("InitSha512 failed");
|
CYASSL_MSG("InitSha512 failed");
|
||||||
return 0; /* not confirmed */
|
return 0; /* not confirmed */
|
||||||
}
|
}
|
||||||
Sha512Update(&sha512, buf, bufSz);
|
|
||||||
Sha512Final(&sha512, digest);
|
ret = Sha512Update(&sha512, buf, bufSz);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Sha512Update failed");
|
||||||
|
return 0; /* not confirmed */
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = Sha512Final(&sha512, digest);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Sha512Final failed");
|
||||||
|
return 0; /* not confirmed */
|
||||||
|
}
|
||||||
|
|
||||||
typeH = SHA512h;
|
typeH = SHA512h;
|
||||||
digestSz = SHA512_DIGEST_SIZE;
|
digestSz = SHA512_DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
@@ -2730,8 +2752,19 @@ static int ConfirmSignature(const byte* buf, word32 bufSz,
|
|||||||
CYASSL_MSG("InitSha384 failed");
|
CYASSL_MSG("InitSha384 failed");
|
||||||
return 0; /* not confirmed */
|
return 0; /* not confirmed */
|
||||||
}
|
}
|
||||||
Sha384Update(&sha384, buf, bufSz);
|
|
||||||
Sha384Final(&sha384, digest);
|
ret = Sha384Update(&sha384, buf, bufSz);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Sha384Update failed");
|
||||||
|
return 0; /* not confirmed */
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = Sha384Final(&sha384, digest);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Sha384Final failed");
|
||||||
|
return 0; /* not confirmed */
|
||||||
|
}
|
||||||
|
|
||||||
typeH = SHA384h;
|
typeH = SHA384h;
|
||||||
digestSz = SHA384_DIGEST_SIZE;
|
digestSz = SHA384_DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
@@ -4763,30 +4796,43 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
|
|||||||
(void)eccKey;
|
(void)eccKey;
|
||||||
|
|
||||||
if (sigAlgoType == CTC_MD5wRSA) {
|
if (sigAlgoType == CTC_MD5wRSA) {
|
||||||
Md5 md5;
|
Md5 md5;
|
||||||
|
|
||||||
InitMd5(&md5);
|
InitMd5(&md5);
|
||||||
Md5Update(&md5, buffer, sz);
|
Md5Update(&md5, buffer, sz);
|
||||||
Md5Final(&md5, digest);
|
Md5Final(&md5, digest);
|
||||||
|
|
||||||
digestSz = MD5_DIGEST_SIZE;
|
digestSz = MD5_DIGEST_SIZE;
|
||||||
typeH = MD5h;
|
typeH = MD5h;
|
||||||
}
|
}
|
||||||
else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) {
|
else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) {
|
||||||
Sha sha;
|
Sha sha;
|
||||||
|
|
||||||
ret = InitSha(&sha);
|
ret = InitSha(&sha);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ShaUpdate(&sha, buffer, sz);
|
ShaUpdate(&sha, buffer, sz);
|
||||||
ShaFinal(&sha, digest);
|
ShaFinal(&sha, digest);
|
||||||
|
|
||||||
digestSz = SHA_DIGEST_SIZE;
|
digestSz = SHA_DIGEST_SIZE;
|
||||||
typeH = SHAh;
|
typeH = SHAh;
|
||||||
}
|
}
|
||||||
else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) {
|
else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) {
|
||||||
Sha256 sha256;
|
Sha256 sha256;
|
||||||
|
|
||||||
ret = InitSha256(&sha256);
|
ret = InitSha256(&sha256);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha256Update(&sha256, buffer, sz);
|
|
||||||
Sha256Final(&sha256, digest);
|
ret = Sha256Update(&sha256, buffer, sz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = Sha256Final(&sha256, digest);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
digestSz = SHA256_DIGEST_SIZE;
|
digestSz = SHA256_DIGEST_SIZE;
|
||||||
typeH = SHA256h;
|
typeH = SHA256h;
|
||||||
}
|
}
|
||||||
|
@@ -291,12 +291,23 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
|
|||||||
ret = InitSha256(&sha256);
|
ret = InitSha256(&sha256);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
break;
|
break;
|
||||||
Sha256Update(&sha256, buffer, totalLen);
|
|
||||||
Sha256Final(&sha256, Ai);
|
ret = Sha256Update(&sha256, buffer, totalLen);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = Sha256Final(&sha256, Ai);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
for (i = 1; i < iterations; i++) {
|
for (i = 1; i < iterations; i++) {
|
||||||
Sha256Update(&sha256, Ai, u);
|
ret = Sha256Update(&sha256, Ai, u);
|
||||||
Sha256Final(&sha256, Ai);
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = Sha256Final(&sha256, Ai);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -307,12 +318,23 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
|
|||||||
ret = InitSha512(&sha512);
|
ret = InitSha512(&sha512);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
break;
|
break;
|
||||||
Sha512Update(&sha512, buffer, totalLen);
|
|
||||||
Sha512Final(&sha512, Ai);
|
ret = Sha512Update(&sha512, buffer, totalLen);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = Sha512Final(&sha512, Ai);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
for (i = 1; i < iterations; i++) {
|
for (i = 1; i < iterations; i++) {
|
||||||
Sha512Update(&sha512, Ai, u);
|
ret = Sha512Update(&sha512, Ai, u);
|
||||||
Sha512Final(&sha512, Ai);
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = Sha512Final(&sha512, Ai);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -3679,8 +3679,10 @@ int pbkdf2_test(void)
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PBKDF2(derived, (byte*)passwd, (int)strlen(passwd), salt, 8, iterations,
|
int ret = PBKDF2(derived, (byte*)passwd, (int)strlen(passwd), salt, 8,
|
||||||
kLen, SHA);
|
iterations, kLen, SHA);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (memcmp(derived, verify, sizeof(verify)) != 0)
|
if (memcmp(derived, verify, sizeof(verify)) != 0)
|
||||||
return -102;
|
return -102;
|
||||||
|
229
src/internal.c
229
src/internal.c
@@ -113,7 +113,7 @@ static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
static void BuildCertHashes(CYASSL* ssl, Hashes* hashes);
|
static int BuildCertHashes(CYASSL* ssl, Hashes* hashes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void PickHashSigAlgo(CYASSL* ssl,
|
static void PickHashSigAlgo(CYASSL* ssl,
|
||||||
@@ -2384,7 +2384,7 @@ ProtocolVersion MakeDTLSv1_2(void)
|
|||||||
|
|
||||||
|
|
||||||
/* add output to md5 and sha handshake hashes, exclude record header */
|
/* add output to md5 and sha handshake hashes, exclude record header */
|
||||||
static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
|
static int HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
|
||||||
{
|
{
|
||||||
const byte* adj = output + RECORD_HEADER_SZ + ivSz;
|
const byte* adj = output + RECORD_HEADER_SZ + ivSz;
|
||||||
sz -= RECORD_HEADER_SZ;
|
sz -= RECORD_HEADER_SZ;
|
||||||
@@ -2405,18 +2405,26 @@ static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
Sha256Update(&ssl->hashSha256, adj, sz);
|
ret = Sha256Update(&ssl->hashSha256, adj, sz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
Sha384Update(&ssl->hashSha384, adj, sz);
|
ret = Sha384Update(&ssl->hashSha384, adj, sz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* add input to md5 and sha handshake hashes, include handshake header */
|
/* add input to md5 and sha handshake hashes, include handshake header */
|
||||||
static void HashInput(CYASSL* ssl, const byte* input, int sz)
|
static int HashInput(CYASSL* ssl, const byte* input, int sz)
|
||||||
{
|
{
|
||||||
const byte* adj = input - HANDSHAKE_HEADER_SZ;
|
const byte* adj = input - HANDSHAKE_HEADER_SZ;
|
||||||
sz += HANDSHAKE_HEADER_SZ;
|
sz += HANDSHAKE_HEADER_SZ;
|
||||||
@@ -2438,13 +2446,21 @@ static void HashInput(CYASSL* ssl, const byte* input, int sz)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
Sha256Update(&ssl->hashSha256, adj, sz);
|
ret = Sha256Update(&ssl->hashSha256, adj, sz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
Sha384Update(&ssl->hashSha384, adj, sz);
|
ret = Sha384Update(&ssl->hashSha384, adj, sz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3826,7 +3842,9 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
if (*inOutIdx + size > totalSz)
|
if (*inOutIdx + size > totalSz)
|
||||||
return INCOMPLETE_DATA;
|
return INCOMPLETE_DATA;
|
||||||
|
|
||||||
HashInput(ssl, input + *inOutIdx, size);
|
ret = HashInput(ssl, input + *inOutIdx, size);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
/* add name later, add on record and handshake header part back on */
|
/* add name later, add on record and handshake header part back on */
|
||||||
@@ -4510,8 +4528,11 @@ static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
|
|||||||
|
|
||||||
InitSha256(&sha256); /* no error check on purpose, dummy round */
|
InitSha256(&sha256); /* no error check on purpose, dummy round */
|
||||||
|
|
||||||
for (i = 0; i < rounds; i++)
|
for (i = 0; i < rounds; i++) {
|
||||||
Sha256Update(&sha256, data, sz);
|
Sha256Update(&sha256, data, sz);
|
||||||
|
/* no error check on purpose, dummy round */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -4526,8 +4547,10 @@ static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
|
|||||||
|
|
||||||
InitSha384(&sha384); /* no error check on purpose, dummy round */
|
InitSha384(&sha384); /* no error check on purpose, dummy round */
|
||||||
|
|
||||||
for (i = 0; i < rounds; i++)
|
for (i = 0; i < rounds; i++) {
|
||||||
Sha384Update(&sha384, data, sz);
|
Sha384Update(&sha384, data, sz);
|
||||||
|
/* no error check on purpose, dummy round */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -4542,8 +4565,10 @@ static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
|
|||||||
|
|
||||||
InitSha512(&sha512); /* no error check on purpose, dummy round */
|
InitSha512(&sha512); /* no error check on purpose, dummy round */
|
||||||
|
|
||||||
for (i = 0; i < rounds; i++)
|
for (i = 0; i < rounds; i++) {
|
||||||
Sha512Update(&sha512, data, sz);
|
Sha512Update(&sha512, data, sz);
|
||||||
|
/* no error check on purpose, dummy round */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -5491,7 +5516,7 @@ static void BuildSHA_CertVerify(CYASSL* ssl, byte* digest)
|
|||||||
|
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
|
|
||||||
static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
|
static int BuildCertHashes(CYASSL* ssl, Hashes* hashes)
|
||||||
{
|
{
|
||||||
/* store current states, building requires get_digest which resets state */
|
/* store current states, building requires get_digest which resets state */
|
||||||
#ifndef NO_OLD_TLS
|
#ifndef NO_OLD_TLS
|
||||||
@@ -5511,11 +5536,17 @@ static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
|
|||||||
ShaFinal(&ssl->hashSha, hashes->sha);
|
ShaFinal(&ssl->hashSha, hashes->sha);
|
||||||
#endif
|
#endif
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
Sha256Final(&ssl->hashSha256, hashes->sha256);
|
ret = Sha256Final(&ssl->hashSha256, hashes->sha256);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
Sha384Final(&ssl->hashSha384, hashes->sha384);
|
ret = Sha384Final(&ssl->hashSha384, hashes->sha384);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5537,6 +5568,8 @@ static void BuildCertHashes(CYASSL* ssl, Hashes* hashes)
|
|||||||
ssl->hashSha384 = sha384;
|
ssl->hashSha384 = sha384;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CYASSL_LEANPSK */
|
#endif /* CYASSL_LEANPSK */
|
||||||
@@ -5606,7 +5639,9 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
|
|||||||
idx += inSz;
|
idx += inSz;
|
||||||
|
|
||||||
if (type == handshake) {
|
if (type == handshake) {
|
||||||
HashOutput(ssl, output, headerSz + inSz, ivSz);
|
ret = HashOutput(ssl, output, headerSz + inSz, ivSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssl->specs.cipher_type == block) {
|
if (ssl->specs.cipher_type == block) {
|
||||||
@@ -5832,7 +5867,11 @@ int SendCertificate(CYASSL* ssl)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
||||||
if (ssl->toInfoOn)
|
if (ssl->toInfoOn)
|
||||||
@@ -5908,7 +5947,10 @@ int SendCertificateRequest(CYASSL* ssl)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@@ -7576,7 +7618,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
||||||
|
|
||||||
@@ -8090,20 +8135,36 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
ret = InitSha256(&sha256);
|
ret = InitSha256(&sha256);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
|
ret = Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
|
if (ret != 0)
|
||||||
Sha256Update(&sha256, messageVerify, verifySz);
|
return ret;
|
||||||
Sha256Final(&sha256, hash256);
|
ret = Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha256Update(&sha256, messageVerify, verifySz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha256Final(&sha256, hash256);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
ret = InitSha384(&sha384);
|
ret = InitSha384(&sha384);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
|
ret = Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
|
if (ret != 0)
|
||||||
Sha384Update(&sha384, messageVerify, verifySz);
|
return ret;
|
||||||
Sha384Final(&sha384, hash384);
|
ret = Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha384Update(&sha384, messageVerify, verifySz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha384Final(&sha384, hash384);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
@@ -8502,7 +8563,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@@ -8562,7 +8626,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
output = ssl->buffers.outputBuffer.buffer +
|
output = ssl->buffers.outputBuffer.buffer +
|
||||||
ssl->buffers.outputBuffer.length;
|
ssl->buffers.outputBuffer.length;
|
||||||
|
|
||||||
BuildCertHashes(ssl, &ssl->certHashes);
|
ret = BuildCertHashes(ssl, &ssl->certHashes);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
ecc_init(&eccKey);
|
ecc_init(&eccKey);
|
||||||
@@ -8769,7 +8835,8 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
@@ -8888,7 +8955,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@@ -8972,7 +9042,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
idx += HINT_LEN_SZ;
|
idx += HINT_LEN_SZ;
|
||||||
XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
|
XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
|
||||||
|
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@@ -9147,20 +9219,36 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
ret = InitSha256(&sha256);
|
ret = InitSha256(&sha256);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
|
ret = Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
|
if (ret != 0)
|
||||||
Sha256Update(&sha256, output + preSigIdx, preSigSz);
|
return ret;
|
||||||
Sha256Final(&sha256, hash256);
|
ret = Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha256Update(&sha256, output + preSigIdx, preSigSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha256Final(&sha256, hash256);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
ret = InitSha384(&sha384);
|
ret = InitSha384(&sha384);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
|
ret = Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
|
if (ret != 0)
|
||||||
Sha384Update(&sha384, output + preSigIdx, preSigSz);
|
return ret;
|
||||||
Sha384Final(&sha384, hash384);
|
ret = Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha384Update(&sha384, output + preSigIdx, preSigSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha384Final(&sha384, hash384);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
if (ssl->suites->sigAlgo == rsa_sa_algo) {
|
if (ssl->suites->sigAlgo == rsa_sa_algo) {
|
||||||
@@ -9295,7 +9383,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddHeaders(output, length, server_key_exchange, ssl);
|
AddHeaders(output, length, server_key_exchange, ssl);
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@@ -9480,20 +9571,36 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
ret = InitSha256(&sha256);
|
ret = InitSha256(&sha256);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
|
ret = Sha256Update(&sha256, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
|
if (ret != 0)
|
||||||
Sha256Update(&sha256, output + preSigIdx, preSigSz);
|
return ret;
|
||||||
Sha256Final(&sha256, hash256);
|
ret = Sha256Update(&sha256, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha256Update(&sha256, output + preSigIdx, preSigSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha256Final(&sha256, hash256);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
ret = InitSha384(&sha384);
|
ret = InitSha384(&sha384);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
|
ret = Sha384Update(&sha384, ssl->arrays->clientRandom, RAN_LEN);
|
||||||
Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
|
if (ret != 0)
|
||||||
Sha384Update(&sha384, output + preSigIdx, preSigSz);
|
return ret;
|
||||||
Sha384Final(&sha384, hash384);
|
ret = Sha384Update(&sha384, ssl->arrays->serverRandom, RAN_LEN);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha384Update(&sha384, output + preSigIdx, preSigSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = Sha384Final(&sha384, hash384);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
if (ssl->suites->sigAlgo == rsa_sa_algo) {
|
if (ssl->suites->sigAlgo == rsa_sa_algo) {
|
||||||
@@ -9559,7 +9666,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
@@ -10169,8 +10279,12 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
if (IsAtLeastTLSv1_2(ssl))
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
Sha256Update(&ssl->hashSha256, input + idx, sz);
|
int shaRet = Sha256Update(&ssl->hashSha256, input + idx, sz);
|
||||||
|
|
||||||
|
if (shaRet != 0)
|
||||||
|
return shaRet;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* does this value mean client_hello? */
|
/* does this value mean client_hello? */
|
||||||
@@ -10772,7 +10886,11 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
|
AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
|
||||||
@@ -10819,7 +10937,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
ssl->IOCB_CookieCtx)) < 0)
|
ssl->IOCB_CookieCtx)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
HashOutput(ssl, output, sendSz, 0);
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
|
AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
|
||||||
@@ -11144,7 +11265,7 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
|
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
if (ssl->options.verifyPeer)
|
if (ssl->options.verifyPeer)
|
||||||
BuildCertHashes(ssl, &ssl->certHashes);
|
ret = BuildCertHashes(ssl, &ssl->certHashes);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/ssl.c
20
src/ssl.c
@@ -4985,8 +4985,18 @@ static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error)
|
|||||||
*error = ret;
|
*error = ret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Sha256Update(&sha256, sessionID, len);
|
|
||||||
Sha256Final(&sha256, digest);
|
ret = Sha256Update(&sha256, sessionID, len);
|
||||||
|
if (ret != 0) {
|
||||||
|
*error = ret;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = Sha256Final(&sha256, digest);
|
||||||
|
if (ret != 0) {
|
||||||
|
*error = ret;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return MakeWordFromHash(digest);
|
return MakeWordFromHash(digest);
|
||||||
}
|
}
|
||||||
@@ -6570,6 +6580,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
CYASSL_ENTER("SHA256_Update");
|
CYASSL_ENTER("SHA256_Update");
|
||||||
Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
|
Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz);
|
||||||
|
/* OpenSSL compat, no error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6577,6 +6588,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
CYASSL_ENTER("SHA256_Final");
|
CYASSL_ENTER("SHA256_Final");
|
||||||
Sha256Final((Sha256*)sha, input);
|
Sha256Final((Sha256*)sha, input);
|
||||||
|
/* OpenSSL compat, no error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6597,6 +6609,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
CYASSL_ENTER("SHA384_Update");
|
CYASSL_ENTER("SHA384_Update");
|
||||||
Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
|
Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz);
|
||||||
|
/* OpenSSL compat, no error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6604,6 +6617,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
CYASSL_ENTER("SHA384_Final");
|
CYASSL_ENTER("SHA384_Final");
|
||||||
Sha384Final((Sha384*)sha, input);
|
Sha384Final((Sha384*)sha, input);
|
||||||
|
/* OpenSSL compat, no error */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CYASSL_SHA384 */
|
#endif /* CYASSL_SHA384 */
|
||||||
@@ -6626,6 +6640,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
CYASSL_ENTER("SHA512_Update");
|
CYASSL_ENTER("SHA512_Update");
|
||||||
Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
|
Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz);
|
||||||
|
/* OpenSSL compat, no error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6633,6 +6648,7 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
|||||||
{
|
{
|
||||||
CYASSL_ENTER("SHA512_Final");
|
CYASSL_ENTER("SHA512_Final");
|
||||||
Sha512Final((Sha512*)sha, input);
|
Sha512Final((Sha512*)sha, input);
|
||||||
|
/* OpenSSL compat, no error */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CYASSL_SHA512 */
|
#endif /* CYASSL_SHA512 */
|
||||||
|
52
src/tls.c
52
src/tls.c
@@ -111,21 +111,35 @@ static int p_hash(byte* result, word32 resLen, const byte* secret,
|
|||||||
ret = HmacSetKey(&hmac, hash, secret, secLen);
|
ret = HmacSetKey(&hmac, hash, secret, secLen);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
|
ret = HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
|
||||||
HmacFinal(&hmac, previous); /* A1 */
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = HmacFinal(&hmac, previous); /* A1 */
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
for (i = 0; i < times; i++) {
|
for (i = 0; i < times; i++) {
|
||||||
HmacUpdate(&hmac, previous, len);
|
ret = HmacUpdate(&hmac, previous, len);
|
||||||
HmacUpdate(&hmac, seed, seedLen);
|
if (ret != 0)
|
||||||
HmacFinal(&hmac, current);
|
return ret;
|
||||||
|
ret = HmacUpdate(&hmac, seed, seedLen);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = HmacFinal(&hmac, current);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if ( (i == lastTime) && lastLen)
|
if ( (i == lastTime) && lastLen)
|
||||||
XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
|
XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
|
||||||
else {
|
else {
|
||||||
XMEMCPY(&result[idx], current, len);
|
XMEMCPY(&result[idx], current, len);
|
||||||
idx += len;
|
idx += len;
|
||||||
HmacUpdate(&hmac, previous, len);
|
ret = HmacUpdate(&hmac, previous, len);
|
||||||
HmacFinal(&hmac, previous);
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = HmacFinal(&hmac, previous);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XMEMSET(previous, 0, sizeof previous);
|
XMEMSET(previous, 0, sizeof previous);
|
||||||
@@ -251,13 +265,21 @@ int BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
|||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
if (ssl->specs.mac_algorithm <= sha256_mac) {
|
if (ssl->specs.mac_algorithm <= sha256_mac) {
|
||||||
Sha256Final(&ssl->hashSha256, handshake_hash);
|
int ret = Sha256Final(&ssl->hashSha256, handshake_hash);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
hashSz = SHA256_DIGEST_SIZE;
|
hashSz = SHA256_DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CYASSL_SHA384
|
#ifdef CYASSL_SHA384
|
||||||
if (ssl->specs.mac_algorithm == sha384_mac) {
|
if (ssl->specs.mac_algorithm == sha384_mac) {
|
||||||
Sha384Final(&ssl->hashSha384, handshake_hash);
|
int ret = Sha384Final(&ssl->hashSha384, handshake_hash);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
hashSz = SHA384_DIGEST_SIZE;
|
hashSz = SHA384_DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -535,9 +557,15 @@ int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
|
|||||||
CyaSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
|
CyaSSL_GetMacSecret(ssl, verify), ssl->specs.hash_size);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
HmacUpdate(&hmac, myInner, sizeof(myInner));
|
ret = HmacUpdate(&hmac, myInner, sizeof(myInner));
|
||||||
HmacUpdate(&hmac, in, sz); /* content */
|
if (ret != 0)
|
||||||
HmacFinal(&hmac, digest);
|
return ret;
|
||||||
|
ret = HmacUpdate(&hmac, in, sz); /* content */
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
ret = HmacFinal(&hmac, digest);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user