Topic: Excluding MD5 causes build errors in 2.9.0

Hi,

I'm cross compiling wolfSSL embedded SSL 2.9.0 for ARM Cortex-M3 from Linux x86_64. Since the target is rather small, I tried stripping it down as far as possible. When excluding MD5, it throws up:

src/internal.c: In function 'DoServerKeyExchange':
src/internal.c:7921:42: error: 'MD5_DIGEST_SIZE' undeclared (first use in this function)
                         digest   = &hash[MD5_DIGEST_SIZE];

The code in question looks highly suspicious to me

                if (hashAlgo == sha_mac) {
                    #ifndef NO_SHA
                        digest   = &hash[MD5_DIGEST_SIZE];
                        digestSz = SHA_DIGEST_SIZE;
                    #endif
                }

Why is MD5_DIGEST_SIZE referred here when it's all about SHA1? This seems very odd (and could warrant at least an explanatory comment that this is indeed what is intended?).

Attached patch makes it at least compile. However, since I do not know if it was intended that way, I'm unsure if it breaks things. Caveat emptor!

Please advice if this is a bug or not,
Thanks in advance and best regards,
Johannes

diff -r -C 5 cyassl-2.9.0-orig/src/internal.c cyassl-2.9.0/src/internal.c
*** cyassl-2.9.0-orig/src/internal.c    2014-02-07 15:28:18.000000000 +0100
--- cyassl-2.9.0/src/internal.c    2014-02-12 12:40:18.291000016 +0100
***************
*** 7847,7868 ****
  
              if (IsAtLeastTLSv1_2(ssl)) {
                  byte   encodedSig[MAX_ENCODED_SIG_SZ];
                  word32 encSigSz;
  #ifndef NO_OLD_TLS
!                 byte*  digest = &hash[MD5_DIGEST_SIZE];
                  int    typeH = SHAh;
                  int    digestSz = SHA_DIGEST_SIZE;
  #else
                  byte*  digest = hash256;
                  int    typeH =  SHA256h;
                  int    digestSz = SHA256_DIGEST_SIZE;
  #endif
  
                  if (hashAlgo == sha_mac) {
                      #ifndef NO_SHA
!                         digest   = &hash[MD5_DIGEST_SIZE];
                          typeH    = SHAh;
                          digestSz = SHA_DIGEST_SIZE;
                      #endif
                  }
                  else if (hashAlgo == sha256_mac) {
--- 7847,7868 ----
  
              if (IsAtLeastTLSv1_2(ssl)) {
                  byte   encodedSig[MAX_ENCODED_SIG_SZ];
                  word32 encSigSz;
  #ifndef NO_OLD_TLS
!                 byte*  digest = &hash[SHA_DIGEST_SIZE];
                  int    typeH = SHAh;
                  int    digestSz = SHA_DIGEST_SIZE;
  #else
                  byte*  digest = hash256;
                  int    typeH =  SHA256h;
                  int    digestSz = SHA256_DIGEST_SIZE;
  #endif
  
                  if (hashAlgo == sha_mac) {
                      #ifndef NO_SHA
!                         digest   = &hash[SHA_DIGEST_SIZE];
                          typeH    = SHAh;
                          digestSz = SHA_DIGEST_SIZE;
                      #endif
                  }
                  else if (hashAlgo == sha256_mac) {
***************
*** 7916,7926 ****
                  return NO_PEER_KEY;
  
              if (IsAtLeastTLSv1_2(ssl)) {
                  if (hashAlgo == sha_mac) {
                      #ifndef NO_SHA
!                         digest   = &hash[MD5_DIGEST_SIZE];
                          digestSz = SHA_DIGEST_SIZE;
                      #endif
                  }
                  else if (hashAlgo == sha256_mac) {
                      #ifndef NO_SHA256
--- 7916,7926 ----
                  return NO_PEER_KEY;
  
              if (IsAtLeastTLSv1_2(ssl)) {
                  if (hashAlgo == sha_mac) {
                      #ifndef NO_SHA
!                         digest   = &hash[SHA_DIGEST_SIZE];
                          digestSz = SHA_DIGEST_SIZE;
                      #endif
                  }
                  else if (hashAlgo == sha256_mac) {
                      #ifndef NO_SHA256
***************
*** 8873,8883 ****
                          if (ssl->ctx->RsaSignCb)
                              doUserRsa = 1;
                      #endif /*HAVE_PK_CALLBACKS */
  
                      if (IsAtLeastTLSv1_2(ssl)) {
!                         byte* digest   = &hash[MD5_DIGEST_SIZE];
                          int   typeH    = SHAh;
                          int   digestSz = SHA_DIGEST_SIZE;
  
                          if (ssl->suites->hashAlgo == sha256_mac) {
                              #ifndef NO_SHA256
--- 8873,8883 ----
                          if (ssl->ctx->RsaSignCb)
                              doUserRsa = 1;
                      #endif /*HAVE_PK_CALLBACKS */
  
                      if (IsAtLeastTLSv1_2(ssl)) {
!                         byte* digest   = &hash[SHA_DIGEST_SIZE];
                          int   typeH    = SHAh;
                          int   digestSz = SHA_DIGEST_SIZE;
  
                          if (ssl->suites->hashAlgo == sha256_mac) {
                              #ifndef NO_SHA256
***************
*** 8944,8954 ****
                      #endif /*HAVE_PK_CALLBACKS */
  
                      if (IsAtLeastTLSv1_2(ssl)) {
                          if (ssl->suites->hashAlgo == sha_mac) {
                              #ifndef NO_SHA
!                                 digest   = &hash[MD5_DIGEST_SIZE];
                                  digestSz = SHA_DIGEST_SIZE;
                              #endif
                          }
                          else if (ssl->suites->hashAlgo == sha256_mac) {
                              #ifndef NO_SHA256
--- 8944,8954 ----
                      #endif /*HAVE_PK_CALLBACKS */
  
                      if (IsAtLeastTLSv1_2(ssl)) {
                          if (ssl->suites->hashAlgo == sha_mac) {
                              #ifndef NO_SHA
!                                 digest   = &hash[SHA_DIGEST_SIZE];
                                  digestSz = SHA_DIGEST_SIZE;
                              #endif
                          }
                          else if (ssl->suites->hashAlgo == sha256_mac) {
                              #ifndef NO_SHA256

Share

Re: Excluding MD5 causes build errors in 2.9.0

The fact it doesn't compile is a bug. That was an oversight.

That variable hash is used to calculate the "finished" hash, which is an concatenation of the MD5 and SHA-1 hashes of the messages concatenated together and then encrypted. That hash array is of length FINISHED_SZ, or SHA_DIGEST_SIZE + MD5_DIGEST_SIZE. For TLSv1.2, they decided that just the specified hash should be used, and they added the ability to specify other hashes like SHA-256 and SHA-384, which we also support. The strange looking &hash[MD5_HASH_SIZE] is trying to set the pointer into the hash storage after the old MD5 portion. (Trying to do it the new way while letting the old way work.)

Unless you change the value of FINISHED_SZ, you are getting a buffer overflow with your patch.

Which configure settings are you using? I'm guessing you have at the least:

$ ./configure --disable-oldtls --disable-md5