CYASSL RTCS HTTPS Fails to Load Web Page

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CYASSL RTCS HTTPS Fails to Load Web Page

1,399 Views
danieldelatorre
Contributor IV

So I have been having an issue while evaluating cyassl security stack that now comes native to the MQX 4.2.0 RTOS.  The problem that I have been seeing is that after I load our products' https’ main page and establish a separate SSL connection (non https, generic secure connection that has a proprietary app layer that rides immediately on top of cyassl secure layer) I then click on another link on the web page I get a bad mac error. 

What I mean by the non https connection is that I have written firmware so that it is also listening on port 2000 where the unit accepts secure connections, this kind of acts like SSH but much simpler.  After I connect to the generic ssl secure socket using a popular ssl terminal program (openssl s_client app as seen below) I then click on a link on the web page (keep in mind this happens a few seconds after the connection has been successfully established with openssl) although it doesn't load.  The web page will load if I simply retry, so the good news is that we always seem to recover from this but I don't want to have a product where the customer needs to constantly retry loading web pages if they don't load the first time.  BTW, I have tried this on chrome, IE, and Firefox and they all show the same symptom.

To repeat the error this what I did:

  1. Loaded our main page:

1.png

2. I then successfully established a connection on port 2000 using openssl s_client application as seen below.

2.png

3. I then clicked on configuration button as seen below.

3.png

4. After I clicked on the link, I get the following error from firefox.

4.png

5. While all of this is happening I have a wireshark trace running, below is where I think the error is happening.  I have attached the wireshark trace to this email, if you didn’t get it please let me know as soon as possible.

5.png

FYI, MQX http stack opens and immediately closes an http session after it has load the page on the client side hence why you might notice that there are multiple ssl session happening consecutively.

I have dug deep into MQX’s implementation of CYASSL and it appears that they have wrapped the CYASSL API with a module called rtcs_ssl, I have attached the module for your reference.  My generic p2000 tcp server code also uses the same module.  At first I suspected something wrong with how the rtcs_ssl uses one mutex for all ssl objects and for ssl context although after a lot of testing and instances of where I created debug code so that each ssl object gets their own mutex I got nowhere on this particular issue.  BTW,  I have backed off all of my changes to rtcs_ssl so I’m pretty much back to exactly what mqx gave me.  I made sure to follow cyassl’s manual suggestions on thread safety.  After thinking about this further, the test that I have just described should not run into the issues that I thought were happening in regards to thread safety, i.e., after I have established a p2000 connection using openssl s_client app the https has already closed the previous session and should simply allow a new session to start after I click on the link.  I have debugged the MQX rtos code with my debugger in that I made sure that the http stack was calling rtcs_shutdown (which internally calls cyassl_free()) and that it closes the socket using the appropriate calls. I’m not convinced that MQX http stack is good, from looking at the wireshark trace I’m starting to suspect  that something went wrong with the encrypted handshake hence why my pc sent a bad mac alert which caused my firmware to send a RST packet (i.e., reset) as seen below.

  6.png

Also, I have thought about upgrading cyassl that now comes with mqx 4.2 because that version is at 3.3 and from what I understand is that wolfssl is now at 3.6.6 which indicates that we are behind by quite a bit.  Would upgrading help or solve my situation?  Any help on this issue would be greatly appreciated.

Labels (1)
0 Kudos
5 Replies

951 Views
danieldelatorre
Contributor IV

WolfSSL got back to me on the problem.  Essentially they told me that the handshake negotiation was failing because we were not generating a random key like we were suppose to.  The issue had to do with MQX's 4.2.0 Cyassl Distribution of code using the default "stub" function for the seed generation, i.e., frdm-k64 demo of https is using the following code for generating the seed:

int GenerateSeed(OS_Seed* os, byte* output, word32 sz)

        {

            int i;

            for (i = 0; i < sz; i++ )

                output[i] = i;

            return 0;

        }

Which as you can see is not random and was causing the "bad MAC" errors.  So I ended up using the following:

     int GenerateSeed(OS_Seed* os, byte* output, word32 sz)

        {  

            TIME_STRUCT st_Time = { 0 };

           

             _time_get( &st_Time ); 

           

             srand( ((st_Time.SECONDS * 1000) + st_Time.MILLISECONDS) * 25);

            

            for( int i = 0; i < sz; i++ ) {

                output[i] = rand() % 256;

                if ( (i % 8) == 7)

                    srand(((st_Time.SECONDS * 1000) + st_Time.MILLISECONDS)* 25);

            }

            return 0;

        }

and it totally fixed the problem.  I don't want to mark this resolved because I first attempted to use the following:

/*

         * Generates a RNG seed using the Random Number Generator Accelerator

         * on the Kinetis K70. Documentation located in Chapter 37 of

         * K70 Sub-Family Reference Manual (see Note 3 in the README for link).

         */

        int GenerateSeed(OS_Seed* os, byte* output, word32 sz)

        {

            int i;

            /* turn on RNGA module */

            SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;

            /* set SLP bit to 0 - "RNGA is not in sleep mode" */

            RNG_CR &= ~RNG_CR_SLP_MASK;

            /* set HA bit to 1 - "security violations masked" */

            RNG_CR |= RNG_CR_HA_MASK;

            /* set GO bit to 1 - "output register loaded with data" */

            RNG_CR |= RNG_CR_GO_MASK;

            for (i = 0; i < sz; i++) {

                /* wait for RNG FIFO to be full */

                while((RNG_SR & RNG_SR_OREG_LVL(0xF)) == 0) {}

                /* get value */

                output[i] = RNG_OR;

            }

            return 0;

Although I kept getting a hard fault as soon as we would write to RNG_CR register.  In case you are wondering what I'm talking about: I wanted to use K64's random number generator accelerator as apposed to the software solution that I came up with.  When I looked at the preprocessor output I noticed that the pointer addresses were all being expanded out properly, below is a snippet from the preprocessor output (IAR's .i file)

        /*

         * Generates a RNG seed using the Random Number Generator Accelerator

         * on the Kinetis K70. Documentation located in Chapter 37 of

         * K70 Sub-Family Reference Manual (see Note 3 in the README for link).

         */

        int GenerateSeed(OS_Seed* os, byte* output, word32 sz)

        {

            int i;

            /* turn on RNGA module */

            ((((SIM_MemMapPtr)0x40047000u))->SCGC3) |= 0x1u;    -------------------- This is where the fault would occur.

            /* set SLP bit to 0 - "RNGA is not in sleep mode" */

            ((((RNG_MemMapPtr)0x40029000u))->CR) &= ~0x10u;

            /* set HA bit to 1 - "security violations masked" */

            ((((RNG_MemMapPtr)0x40029000u))->CR) |= 0x2u;

            /* set GO bit to 1 - "output register loaded with data" */

            ((((RNG_MemMapPtr)0x40029000u))->CR) |= 0x1u;

            for (i = 0; i < sz; i++) {

                /* wait for RNG FIFO to be full */

                while((((((RNG_MemMapPtr)0x40029000u))->SR) & (((uint32_t)(((uint32_t)(0xF))<<8))&0xFF00u)) == 0) {}

                /* get value */

                output[i] = ((((RNG_MemMapPtr)0x40029000u))->OR);

            }

            return 0;

        }

0 Kudos

951 Views
danieldelatorre
Contributor IV

So i still can't explain why we get a hard fault when writing to the RNG_CR register, so my immediate issue was resolved although I really would much rather prefer to use the RNGA. 

0 Kudos

951 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi

Which board you are using, K70 or K64?

0 Kudos

951 Views
danieldelatorre
Contributor IV

It is the K64, the comments talk about K70 although all of the register names match and properly link up to the definitions defined in MK64F12.h

0 Kudos

951 Views
danielchen
NXP TechSupport
NXP TechSupport

Hi

Regarding the random number generator accelerator, there is a difference between K70 and K64.

For K64frdm, RNGA is accessed through AIPS0,  should define the clock gate control bits in the SCGC6.

Please try to replace your code

SIM_SCGC3 |= SIM_SCGC3_RNGA_MASK;

with

   SIM_SCGC6 |= SIM_SCGC6_RNGA_MASK;

I hope it works for you.

Have a nice day!

Regards

Daniel

0 Kudos