From a281c6bc6c09193ce28b32ce1f41840f5f5b6889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Guimar=C3=A3es?= Date: Tue, 1 Jul 2014 16:53:28 -0300 Subject: [PATCH] asn: refactoring ConfirmSignature to reduce stack usage: --- variable digest moved to the heap (20..64 bytes saved) --- variable pubKey moved to the heap (sizeof(RsaKey) bytes saved) --- variable encodedSig moved to the heap (512 bytes saved) --- variable plain moved to the heap (512 bytes saved) --- variable pubKey moved to the heap (sizeof(ecc_key) bytes saved) --- variable md2 moved to the heap (sizeof(Md2) bytes saved) --- variable md5 moved to the heap (sizeof(Md5) bytes saved) --- variable sha moved to the heap (sizeof(Sha) bytes saved) --- variable sha256 moved to the heap (sizeof(Sha256) bytes saved) --- variable sha384 moved to the heap (sizeof(Sha384) bytes saved) --- variable sha512 moved to the heap (sizeof(Sha512) bytes saved) fix - In some cases, the function was returning error codes, that could be interpreted as a false positive. --- ctaocrypt/src/asn.c | 315 +++++++++++++++++++----------------- cyassl/ctaocrypt/settings.h | 4 + 2 files changed, 175 insertions(+), 144 deletions(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 692e0c78f..e3bbef88b 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -35,14 +35,11 @@ #include #include #include -#include -#include #include +#include #include #include #include -#include -#include #include #include @@ -2842,50 +2839,56 @@ word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID) } -/* return true (1) for Confirmation */ +/* return true (1) or false (0) for Confirmation */ static int ConfirmSignature(const byte* buf, word32 bufSz, const byte* key, word32 keySz, word32 keyOID, const byte* sig, word32 sigSz, word32 sigOID, void* heap) { -#ifdef CYASSL_SHA512 - byte digest[SHA512_DIGEST_SIZE]; /* max size */ -#elif !defined(NO_SHA256) - byte digest[SHA256_DIGEST_SIZE]; /* max size */ -#else - byte digest[SHA_DIGEST_SIZE]; /* max size */ -#endif - int typeH, digestSz, ret = 0; + int typeH = 0, digestSz = 0, ret = 0; + DECLARE_ARRAY(byte, digest, MAX_DIGEST_SIZE); + + if (!CREATE_ARRAY(byte, digest, MAX_DIGEST_SIZE)) + return 0; /* not confirmed */ (void)key; (void)keySz; (void)sig; (void)sigSz; (void)heap; - (void)ret; switch (sigOID) { #ifndef NO_MD5 case CTC_MD5wRSA: { - Md5 md5; - InitMd5(&md5); - Md5Update(&md5, buf, bufSz); - Md5Final(&md5, digest); - typeH = MD5h; - digestSz = MD5_DIGEST_SIZE; + DECLARE_VAR(Md5, md5); + + if (CREATE_VAR(Md5, md5)) { + InitMd5(md5); + Md5Update(md5, buf, bufSz); + Md5Final(md5, digest); + + typeH = MD5h; + digestSz = MD5_DIGEST_SIZE; + DESTROY_VAR(md5); + } } break; #endif #if defined(CYASSL_MD2) case CTC_MD2wRSA: { - Md2 md2; - InitMd2(&md2); - Md2Update(&md2, buf, bufSz); - Md2Final(&md2, digest); - typeH = MD2h; - digestSz = MD2_DIGEST_SIZE; + DECLARE_VAR(Md2, md2); + + if (CREATE_VAR(Md2, md2)) { + InitMd2(md2); + Md2Update(md2, buf, bufSz); + Md2Final(md2, digest); + + typeH = MD2h; + digestSz = MD2_DIGEST_SIZE; + DESTROY_VAR(md2); + } } break; #endif @@ -2894,16 +2897,22 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, case CTC_SHAwDSA: case CTC_SHAwECDSA: { - Sha sha; - ret = InitSha(&sha); - if (ret != 0) { - CYASSL_MSG("InitSha failed"); - return 0; /* not confirmed */ + DECLARE_VAR(Sha, sha); + + if (CREATE_VAR(Sha, sha)) { + if (InitSha(sha) != 0) { + CYASSL_MSG("InitSha failed"); + } + else { + ShaUpdate(sha, buf, bufSz); + ShaFinal(sha, digest); + + typeH = SHAh; + digestSz = SHA_DIGEST_SIZE; + } + + DESTROY_VAR(sha); } - ShaUpdate(&sha, buf, bufSz); - ShaFinal(&sha, digest); - typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; } break; #endif @@ -2911,27 +2920,25 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, case CTC_SHA256wRSA: case CTC_SHA256wECDSA: { - Sha256 sha256; - ret = InitSha256(&sha256); - if (ret != 0) { - CYASSL_MSG("InitSha256 failed"); - return 0; /* not confirmed */ + DECLARE_VAR(Sha256, sha256); + + if (CREATE_VAR(Sha256, sha256)) { + if (InitSha256(sha256) != 0) { + CYASSL_MSG("InitSha256 failed"); + } + else if (Sha256Update(sha256, buf, bufSz) != 0) { + CYASSL_MSG("Sha256Update failed"); + } + else if (Sha256Final(sha256, digest) != 0) { + CYASSL_MSG("Sha256Final failed"); + } + else { + typeH = SHA256h; + digestSz = SHA256_DIGEST_SIZE; + } + + DESTROY_VAR(sha256); } - - 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; - digestSz = SHA256_DIGEST_SIZE; } break; #endif @@ -2939,27 +2946,25 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, case CTC_SHA512wRSA: case CTC_SHA512wECDSA: { - Sha512 sha512; - ret = InitSha512(&sha512); - if (ret != 0) { - CYASSL_MSG("InitSha512 failed"); - return 0; /* not confirmed */ + DECLARE_VAR(Sha512, sha512); + + if (CREATE_VAR(Sha512, sha512)) { + if (InitSha512(sha512) != 0) { + CYASSL_MSG("InitSha512 failed"); + } + else if (Sha512Update(sha512, buf, bufSz) != 0) { + CYASSL_MSG("Sha512Update failed"); + } + else if (Sha512Final(sha512, digest) != 0) { + CYASSL_MSG("Sha512Final failed"); + } + else { + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + } + + DESTROY_VAR(sha512); } - - 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; - digestSz = SHA512_DIGEST_SIZE; } break; #endif @@ -2967,127 +2972,149 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, case CTC_SHA384wRSA: case CTC_SHA384wECDSA: { - Sha384 sha384; - ret = InitSha384(&sha384); - if (ret != 0) { - CYASSL_MSG("InitSha384 failed"); - return 0; /* not confirmed */ - } + DECLARE_VAR(Sha384, sha384); + + if (CREATE_VAR(Sha384, sha384)) { + if (InitSha384(sha384) != 0) { + CYASSL_MSG("InitSha384 failed"); + } + else if (Sha384Update(sha384, buf, bufSz) != 0) { + CYASSL_MSG("Sha384Update failed"); + } + else if (Sha384Final(sha384, digest) != 0) { + CYASSL_MSG("Sha384Final failed"); + } + else { + typeH = SHA384h; + digestSz = SHA384_DIGEST_SIZE; + } - ret = Sha384Update(&sha384, buf, bufSz); - if (ret != 0) { - CYASSL_MSG("Sha384Update failed"); - return 0; /* not confirmed */ + DESTROY_VAR(sha384); } - - ret = Sha384Final(&sha384, digest); - if (ret != 0) { - CYASSL_MSG("Sha384Final failed"); - return 0; /* not confirmed */ - } - - typeH = SHA384h; - digestSz = SHA384_DIGEST_SIZE; } break; #endif default: CYASSL_MSG("Verify Signautre has unsupported type"); - return 0; } - (void)typeH; /* some builds won't read */ + + if (typeH == 0) { + DESTROY_ARRAY(digest); + return 0; /* not confirmed */ + } switch (keyOID) { #ifndef NO_RSA case RSAk: { - RsaKey pubKey; - byte encodedSig[MAX_ENCODED_SIG_SZ]; - byte plain[MAX_ENCODED_SIG_SZ]; word32 idx = 0; int encodedSigSz, verifySz; byte* out; - + DECLARE_VAR(RsaKey, pubKey); + DECLARE_ARRAY(byte, plain, MAX_ENCODED_SIG_SZ); + DECLARE_ARRAY(byte, encodedSig, MAX_ENCODED_SIG_SZ); + if (sigSz > MAX_ENCODED_SIG_SZ) { CYASSL_MSG("Verify Signautre is too big"); - return 0; } - - ret = InitRsaKey(&pubKey, heap); - if (ret != 0) return ret; - if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { + else if (!CREATE_VAR(RsaKey, pubKey)) { + CYASSL_MSG("Failed to allocate pubKey"); + } + else if (InitRsaKey(pubKey, heap) != 0) { + CYASSL_MSG("InitRsaKey failed"); + } + else if (RsaPublicKeyDecode(key, &idx, pubKey, keySz) < 0) { CYASSL_MSG("ASN Key decode error RSA"); - ret = 0; } - else { + else if (CREATE_ARRAY(byte, plain, MAX_ENCODED_SIG_SZ)) { XMEMCPY(plain, sig, sigSz); - if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, - &pubKey)) < 0) { + + if ((verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, + pubKey)) < 0) { CYASSL_MSG("Rsa SSL verify error"); - ret = 0; } - else { + else if (CREATE_ARRAY(byte, encodedSig, MAX_ENCODED_SIG_SZ)) { /* make sure we're right justified */ encodedSigSz = EncodeSignature(encodedSig, digest, digestSz, typeH); if (encodedSigSz != verifySz || XMEMCMP(out, encodedSig, encodedSigSz) != 0) { CYASSL_MSG("Rsa SSL verify match encode error"); - ret = 0; } else ret = 1; /* match */ #ifdef CYASSL_DEBUG_ENCODING { - int x; - printf("cyassl encodedSig:\n"); - for (x = 0; x < encodedSigSz; x++) { - printf("%02x ", encodedSig[x]); - if ( (x % 16) == 15) - printf("\n"); - } - printf("\n"); - printf("actual digest:\n"); - for (x = 0; x < verifySz; x++) { - printf("%02x ", out[x]); - if ( (x % 16) == 15) - printf("\n"); - } - printf("\n"); + int x; + + printf("cyassl encodedSig:\n"); + + for (x = 0; x < encodedSigSz; x++) { + printf("%02x ", encodedSig[x]); + if ( (x % 16) == 15) + printf("\n"); + } + + printf("\n"); + printf("actual digest:\n"); + + for (x = 0; x < verifySz; x++) { + printf("%02x ", out[x]); + if ( (x % 16) == 15) + printf("\n"); + } + + printf("\n"); } #endif /* CYASSL_DEBUG_ENCODING */ + + DESTROY_ARRAY(encodedSig); } + + DESTROY_ARRAY(plain); + } + + if (pubKey) { + FreeRsaKey(pubKey); + DESTROY_VAR(pubKey); } - FreeRsaKey(&pubKey); - return ret; } #endif /* NO_RSA */ #ifdef HAVE_ECC case ECDSAk: { - ecc_key pubKey; - int verify = 0; - - if (ecc_import_x963(key, keySz, &pubKey) < 0) { - CYASSL_MSG("ASN Key import error ECC"); - return 0; - } - - ret = ecc_verify_hash(sig,sigSz,digest,digestSz,&verify,&pubKey); - ecc_free(&pubKey); - if (ret == 0 && verify == 1) - return 1; /* match */ + int verify = 0; + DECLARE_VAR(ecc_key, pubKey); - CYASSL_MSG("ECC Verify didn't match"); - return 0; + if (!CREATE_VAR(ecc_key, pubKey)) { + CYASSL_MSG("Failed to allocate pubKey"); + } + else if (ecc_import_x963(key, keySz, pubKey) < 0) { + CYASSL_MSG("ASN Key import error ECC"); + } + else if (ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, + pubKey) != 0) { + CYASSL_MSG("ECC verify hash error"); + } + else if (1 != verify) { + CYASSL_MSG("ECC Verify didn't match"); + } else + ret = 1; /* match */ + + if (pubKey) { + ecc_free(pubKey); + DESTROY_VAR(pubKey); + } } #endif /* HAVE_ECC */ default: CYASSL_MSG("Verify Key type unknown"); - return 0; } + + DESTROY_ARRAY(digest); + return ret; } diff --git a/cyassl/ctaocrypt/settings.h b/cyassl/ctaocrypt/settings.h index b402114b3..5ec46a994 100644 --- a/cyassl/ctaocrypt/settings.h +++ b/cyassl/ctaocrypt/settings.h @@ -270,6 +270,10 @@ #define DESTROY_ARRAY(var) #endif +#define DECLARE_VAR(type, var) DECLARE_ARRAY(type, var, 1) +#define CREATE_VAR(type, var) CREATE_ARRAY(type, var, 1) +#define DESTROY_VAR(var) DESTROY_ARRAY(var) + #ifdef FREERTOS #ifndef NO_WRITEV #define NO_WRITEV