Aaron Ardiri
[Valid RSS] RSS/XML feed
198 entries available (show all)

 

Internet of Things (IoT)
   

PLEASE TAKE A MOMENT TO FOLLOW MY NEW VENTURE:
 
RIoT Secure AB
 
ALL SECURITY RELATED TOPICS ON IoT wILL BE POSTED THERE


2016-12-16
>> µTLS - DEFINING LIGHTWEIGHT SECURITY FOR IoT (PART 4)

You can never appreciate how valuable resources are until they get out of your reach!

So far, the µTLS (micro TLS) project is coming along well - with promising results that it is definitely feasible to secure the most resource constrained devices out there. It is my hope that this entry cements that reality in your mind and you see a commercial viability for such a solution. By now you should understand the basic architecture and protocol of the solution - let's dig a little deeper now.

In my earlier entry; I provided the basics for the µTLS (micro TLS) server and two protocol implementations - namely, none and rot13. I left it up to the reader to figure out how to modify the client that was provided in order to make it work with the rot13 module - did you even attempt it?

What exactly is required to upgrade our client from none to rot13?

Well; first of all, we need some functions that can perform rot13 on a buffer - taking into consideration that memory is a valuable resource. You can find a number of implementations on the internet, but this is what I eventually ended up using in my example.

    char rot13_single(char c)
    {
           if ((c >= 'a') && (c <= 'z')) return (((c-'a') + 13) % 26)+'a';
      else if ((c >= 'A') && (c <= 'Z')) return (((c-'A') + 13) % 26)+'A';
      else return c;
    }
    
    void rot13(char *src, int len)
    {
      for (int i=0;i<len;i++) src[i] = rot13_single(src[i]);
    }

The next step is to change the communication protocols for the POST and PUT requests:

    @@ -405,7 +424,7 @@
         "{" \
           "\"protocol\":\"none\"," \
           "\"response\":\"none\"," \
    -      "\"protocol_sub\":\"none\"" \
    +      "\"protocol_sub\":\"rot13\"" \
         "}" \
       "}";
     
    @@ -669,8 +688,8 @@
         "\"," \
         "\"security\":" \
         "{" \
    -      "\"protocol\":\"none\"," \
    -      "\"response\":\"none\"" \
    +      "\"protocol\":\"rot13\"," \
    +      "\"response\":\"rot13\"" \
         "}," \
         "\"data\":" \
         "{" \

We want to change the communications protocol such that after the initial request; all communications should be performed using the rot13 substitution cipher. There are no configuration parameters of rot13 - so we only need to makes changes in the PUT handler.

    @@ -700,6 +719,10 @@
       int    msg_len = strlen(msg);
       // --------------------------------------------------------------------
     
    +  // the must encode the message using rot13
    +  rot13(msg, strlen(msg));
    +
    +  // we need to 
     #ifdef ENABLE_DEBUG
       Serial.println(F(":: attempting connection to server"));

First we must encode the message we are sending over to the server, as shown above.

    @@ -855,6 +878,9 @@
     #endif
     #endif
     
    +                // the message has been encoded using rot13
    +                rot13((char *)b, b_len);
    +
     #ifdef ENABLE_DEBUG
                     // display the buffer
                     Serial.print(F("** decoded form: "));

Finally; when we receive a message from the server in the data.buffer key; we just need to decode the buffer that we allocated and copies the base64 decoded message into. Before we discard the memory that was allocated the client should interpret the message of course.

With these changes; you should now have a working rot13 client with the µTLS (microTLS) server.

    Sketch uses 13,738 bytes (42%) of program storage space. 
    Global variables use 443 bytes (21%) of dynamic memory, 
    leaving 1,605 bytes for local variables. Maximum is 2,048 bytes.

In comparison to the none client - there are no changes in the memory foot print as we didn't use any additional variables but there was a small increase in the program storage due to the addition code for performing the rot13 operations - this was expected outcome of course.

GETTING SERIOUS: RC4
RC4 (Rivest Cipher 4) is a simple stream cipher. while remarkable for its simplicity and speed in software, it has been know to have some vulnerabilities; but these can be dealt with by throwing away a number of initial output bytes in the stream - something we can handle in our protocol.

The design of the client we posted earlier had some minor flaws; mainly in regards to how it would deal with accepting a large buffer in the data.buffer key that is exchanged from the server. It was by design to provide a proof-of-concept that would be easy to follow, for my readers.

Some tricks are needed get it to remain stable.


Unfortunately; I currently consider these "trade secrets" - I will not be posting those changes for the public freely at this point. I truly believe there is some commercial viability in µTLS (micro TLS) - with that said, do reach out to me if you want to know more or seek a collaboration.

Now - back to RC4 - it took quite a bit of work - but we have a working RC4 implementation:

    :: attempting connection to server
    ** connected
    -- request:
    POST /xxx/index.php HTTP/1.1
    Host: xxx.xxxxxxxx.xxx
    User-Agent: Arduino/1.0
    Connection: close
    Content-type: application/x-www-form-urlencoded
    Content-Length: 118
    
    {
      "guid": "ffa90e64-f3e2-4697-b98c-e3c13d1b2362",
      "security": {
        "protocol":"none",
        "response":"none",
        "protocol_sub":"rc4"
      }
    }
    -- response:
    HTTP/1.1 200 OK
    Date: Thu, 15 Dec 2016 10:58:06 GMT
    Server: Apache
    Content-Length: 560
    Connection: close
    Content-Type: application/json
    
    {
        "session": "e91f5584152639c72d5358a05f9cd88758527740d09bb",
    ** found session: e91f5584152639c72d5358a05f9cd88758527740d09bb
        "security": {
            "response": "none",
            "protocol": "rc4"
        },
        "data": {
            "ts": "1481886117",
    ** found ts: 1481886117
            "buffer": "AAuEtUUu2zqq1fY22ZivTTlJKOOeAY441FBzzq3kPP/eRSS02y
                       66ehaTTeHMss7ME33FNDZZczwnnTkXFFf8RCCpIc99jzCeeZc6
                       AA+VmLLbv488FKliiRZvEEtDlbbU7r99NS9kkBWvMMF9JHH55W
                       SSz9CXXCb055qJsjjWcqeebuJwwcpFXX65yaauj1uuEt+BB/Rd
                       EEiT8xxBJxJJeQ3tth3eAA/n1++nW0aacA2mm1YZqqiwbDDI4H
                       GGDciTTrxAjj9IyIIQPcMM7x9yyKxK774cZEEjyzFF61miiY2p
                       FFRWCZZbDNbbevmee0ChEEoKwVVFkE88bS+UULXnNNaDJss93Y
                       BBKsG++7tk99wLkrrP5qggq3SyyKmWGGMZfllzfCSSzr/55NcA
                       mm+0hXXD0lssH4j44CxLSSALAqqQ=="
    ** found buffer: *streamed*
    ** decoded form:   02 E1 2D 52 ED B3 AB 57 D8 D9 98 AF 4E 52 4A 39  
                       E0 18 E3 51 41 CE AD E4 3F F7 91 4B 4D B2 E9 E8 
                       5A 4D E1 CC B3 B3 04 DC 53 43 65 CC F0 9D 39 17 
                       15 FF 11 0A 92 1C F6 3C C2 79 97 3A 03 E5 66 2D
                       BB F8 F0 52 A5 89 16 6F 12 D0 E5 6D 4E EB F4 D4
                       BD 90 15 AF 30 5F 49 1F 9E 56 4B 3F 42 5C 26 F4 
                       E6 A2 6C 8D 67 2A 79 BB 89 C1 CA 45 5F AE 72 6A 
                       E8 F5 B8 4B 7E 07 F4 5D 12 24 FC C4 12 71 25 E4 
                       37 B6 1D DE 03 F9 F5 FA 75 B4 69 C0 36 9B 56 19 
                       AA 2C 1B 0C 8E 07 18 37 22 4E BC 40 8F D2 32 21 
                       03 DC 33 BC 7D C8 AC 4A EF 87 19 12 3C B3 17 AD 
                       66 89 8D A9 15 15 82 65 B0 CD 6D EB E6 7B 40 A1 
                       12 82 B0 54 59 04 F1 B4 BE 50 B5 E7 35 A0 C9 B3 
                       DD D8 04 AB 06 FB BB 64 F7 02 E4 AC FE 6A 82 AD 
                       D2 C8 A9 96 18 C6 5F 97 37 C2 4B 3A FF E4 D7 00 
                       9B ED 21 5C 3D 25 B0 7E 23 E0 2C 4B 48 02 C0 A9
        }
    }

Once again; for the sake of readability I manually edited the data being sent and the received data (highlighted in bold) instead of it being on a single line. What you can see from this initial request is the exchange of the 256-byte key that the RC4 algorithm should use for all future communication.

Our goal is now to send an encrypted message and receive an encrypted response from the server.

    :: attempting connection to server
    ** connected
    -- request:
    PUT /xxx/index.php HTTP/1.1
    Host: xxx.xxxxxxxx.xxx
    User-Agent: Arduino/1.0
    Connection: close
    Content-type: application/x-www-form-urlencoded
    Content-Length: 118
    
    {
      "session": "e91f5584152639c72d5358a05f9cd88758527740d09bb",
      "security": {
        "protocol":"rc4",
        "response":"rc4"
      },
      "data": {
        "params":"2073",
        "buffer":"UQLDWadAJPtWkQmMe8lYwkGzhfuPrEFXnOv8kZJxhQ=="
      }
    }
    -- response:
    HTTP/1.1 200 OK
    Date: Fri, 16 Dec 2016 11:02:02 GMT
    Server: Apache
    Content-Length: 293
    Connection: close
    Content-Type: application/json
    
    sending a message over microTLS
    {
        "session": "e91f5584152639c72d5358a05f9cd88758527740d09bb",
        "security": {
            "response": "rc4",
            "protocol": "rc4"
        },
        "data": {
            "ts": "1481886124",
    ** found ts: 1481886124
            "params": "2082",
    ** found params: 2082
            "buffer": "22QuebbMMZ11UXhnnuOPrrEA="
    ** found buffer: *streamed*
    ** decoded form: D9 0B 9E 6C C3 19 D5 45 E1 9E E3 8F AC 40 
    ** ASCII form:   ...l...E.....@
    ** decrypted:    68 6F 77 64 79 20 70 61 72 74 6E 65 72 21 
    ** ASCII form:   howdy partner!
        }
    }

Without going into the specific details; we can argue that since we were able to see the message in the response and decrypt the message from the server without it being garbage - everything works! In order to resolve the security risk of using RC4, we have utilized our data.params key to have some form of dynamic throw-away counter that we should use when using RC4.

So; how does the RC4 client match up compared to the others?

    Sketch uses 15,246 bytes (47%) of program storage space. 
    Global variables use 715 bytes (34%) of dynamic memory, 
    leaving 1,333 bytes for local variables. Maximum is 2,048 bytes.

We have seen an increase of around 1.5kb for the RC4 implementation and 300 bytes additional memory; which accounts for the 256-byte key exchanged when the session is initialized and other variables used as part of our secure random number generator.

While we could argue that the on-going exchange of information between the client and server is secure - until we resolve the initial exchange of the 256-byte RC4 key; it isn't secure for commercial use. We still have plenty of memory available however to implement a secure exchange.


 

advertisement (self plug):
need assistance in an IoT project? contact us for a free consultation.

 



µTLS - defining lightweight security for IoT (part 5)
 
µTLS - defining lightweight security for IoT (part 3)

DISCLAIMER:
All content provided on this blog is for informational purposes only.
All comments are generated by users and moderated for inappropriateness periodically.
The owner will not be liable for any losses, injuries, or damages from the display or use of this information.