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-17
>> µTLS - DEFINING LIGHTWEIGHT SECURITY FOR IoT (PART 5)

I figured it was time to play with the big boys - nothing like implementing an industry standard.

The National Institute of Standards and Technology, a branch in the U. S. Government sought public submissions to establish the Advanced Encryption Standard (AES), and since May 26, 2002 it became effective as a federal government standard - superseding the Data Encryption Standard (DES). The winning submission was Rijndael, and the approved key sizes were 128, 192 and 256. It was initially announced in the FIPS publication FIPS 197.

It is only natural that µTLS add support for AES, as it is frequently as a Cipher in TLS protocols and considered secure if the exchange of keys can be done securely. The FIPS 197 standard documents the algorithm in detail; so writing an implementation was quite simple - however there are a number of public domain sources online which have been verified against test vectors.

On the server side; the plan is to hook into the openssl library within php to encrypt and decrypt AES streams using CBC mode (Cipher Block Chaining). The openssl library uses the PKCS7 padding scheme, where there must be at least one padding byte within the input stream. Something we must take into consideration when writing our Cipher on the micro-controllers.

Suprisingly; the algorithm was simple enough to integrate into the µTLS (micro TLS) server and client sketches - within a few hours I had working examples that could utilize aes-128, aes-192 and aes-256. Our server design is holding up well; only a few minor tweaks were required.

Enough of the technical blah blah blah - let's see this stuff in action!

    :: 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: 283
    
    {
      "guid": "ffa90e64-f3e2-4697-b98c-e3c13d1b2362",
      "security": {
        "protocol": "none",
        "response": "none",
        "protocol_sub": "aes-128"
      }
    }
    -- response:
    HTTP/1.1 200 OK
    Date: Sat, 17 Dec 2016 19:21:40 GMT
    Server: Apache
    Content-Length: 287
    Connection: close
    Content-Type: application/json
    
    {
        "session": "e91f5584152639c72d5358a05f9cd887585590478d0d2",
    ** found session: e91f5584152639c72d5358a05f9cd887585590478d0d2
        "security": {
            "response": "aes-128",
            "protocol": "aes-128"
        },
        "data": {
            "ts": "1482002503",
    ** found ts: 1482002503
            "buffer": "88wx6UUMKPVVLFkyyuMdJJDdovvQ=="
    ** found buffer: *streamed*
    ** decoded form: F3 0C 7A 50 C2 8F 54 B1 64 CA E3 1D 24 37 68 BD 
    ** ASCII form:   ..zP..T.d...$7h.
        }
    }

The client makes the request to the server within the security.protocol_sub key to use aes-128 for the communication once the session has been created. We can see within the response that the 128 bit key (16 bytes) is encapsulated within the response:

F3 0C 7A 50 C2 8F 54 B1 64 CA E3 1D 24 37 68 BD

During the process of implementing AES, I spent a significant amount of time understanding how the algorithm works - it is definitely an interesting read if cryptography is a subject matter that interests you. On the Arduino side; encryption is done as simple as follows:

    char   msg[] = "sending a message over microTLS";
    int    msg_len = strlen(msg);
    
    byte   enc[128]; 
    int    enc_len = (msg_len + AES_BLOCKSIZE) & ~(AES_BLOCKSIZE-1);
    
    // we must create a random IV - put it in first bytes
    for (i=0;i < AES_BLOCKSIZE; i++)
      enc[i] = xrand();
    
    // encode our message
    AESInitState(&aes, app_aeskey, enc);
    AESencrypt(&aes, (byte *)msg, msg_len, enc+AES_BLOCKSIZE);
    enc_len += AES_BLOCKSIZE;

The CBC mode of AES uses an initialization vector (IV); that gets updates after each block of data is encrypted using the algorithm. We generate some random bytes and then initialize the AESEngine. Due to PKCS7 padding; we know that the output buffer will be larger than our input buffer - including the IV in addition to the encoded buffer; it will be of length modulus the block size.

The subsequent PUT request looks as follows:

    :: 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: 199
    
    {
      "session": "e91f5584152639c72d5358a05f9cd887585590478d0d2",
      "security": {
        "protocol": "aes-128",
        "response": "aes-128"
      },
      "data": {
        "buffer": "9PDFlwmTZl57Dz6mqfZGATMNx4OTJb5zsSTTEzt/2sKzlSp
                   Qr1fL2zCIc818Ujzw"
      }
    }
    -- response:
    HTTP/1.1 200 OK
    Date: Sat, 17 Dec 2016 19:22:08 GMT
    Server: Apache
    Content-Length: 299
    Connection: close
    Content-Type: application/json
    
    sending a message over microTLS
    {
        "session": "e91f5584152639c72d5358a05f9cd887585590478d0d2",
        "security": {
            "response": "aes-128",
            "protocol": "aes-128"
        },
        "data": {
            "ts": "1482002531",
    ** found ts: 1482002531
            "buffer": "uuF3CRRYZe55yz7+++kY++UeUCCSnFzzmQ8aa/gBiiy
             xMCCcnX55gU="
    ** found buffer: *streamed*
    ** decoded form: B8 5D C2 45 86 5E E7 2C FB FB E9 18 F9 47 94 09 
                     29 C5 CE 64 3C 6B F8 01 8B 2C 4C 09 C9 D7 E6 05
    ** ASCII form:   .].E.^.,.....G..)..d<k...,L.....
    ** decrypted:    68 6F 77 64 79 20 70 61 72 74 6E 65 72 21 
    ** ASCII form:   howdy partner!
        }
    }

We can clearly see that the message was received and the server response was also decrypted.

    Sketch uses 17,880 bytes (55%) of program storage space. 
    Global variables use 475 bytes (23%) of dynamic memory, 
    leaving 1,573 bytes for local variables. Maximum is 2,048 bytes.

In comparison to the none client, our program increased in size by around 4kb and only a small amount of dynamic memory was sacrificed for the purpose of storing the AES key. Since the algorithm remains the same regardless of the key sizes; we we easily boost up to a 256 byte posing a risk to our free memory.

So; while this is great - how can we make the key exchange secure?

There are a number of ways to do this; the most commonly accepted way is to use public-key cryptography (RSA, ECC et al) - however, the standard also included the use of PSK (pre-shared key) systems also can be marked as secure. For the sake of completeness; I decided to integrate the concept into the flow of the µTLS (micro TLS) protocol.

To implement this; for each client in the system there needs to be a pre-shared key generated. The key will exist securely on the server and compiled into the client. From the out-side world; there is no way to intercept these keys over network traffic.

In order for the server to verify that the client is who they say they are; a buffer is created and encrypted using the shared key. On receival; the server decrypts the buffer and compares it to what it expects it to be. On success; the sub-protocol initialization is encrypted using the same key and send back to the client, effectively doing the key exchange behind a layer of security.

The resulting resource analysis of a sketch using aes-128/aes-128:

    Sketch uses 18,314 bytes (56%) of program storage space. 
    Global variables use 491 bytes (23%) of dynamic memory, 
    leaving 1,557 bytes for local variables. Maximum is 2,048 bytes.
    

There is still plenty of resources available to integrate the RSA algorithm that I had previously written for the Arduino UNO - that will be my next major milestone in the project. By that time; hopefully the IoT world would have picked up wind about µTLS (micro TLS) and we can look at how to get the solution out there to solve the security issues within the IoT ecosystem.


 

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

 



µTLS - defining lightweight security for IoT (part 6)
 
µTLS - defining lightweight security for IoT (part 4)

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.