Encrypted frames

In this chapter we explain how to create encrypted frames using the Waspmote AES libraries.

Encrypted frame format

The encrypted frame is a special binary frame which encapsulates the real encrypted frame as the payload of a new frame. The format of the encrypted frame is as follows:

Where the "Encrypted Payload" is the original frame after being encrypted using the AES algorithm.

Note: Regarding the old Waspmote v12 platform version, a different format is used. Please refer to the corresponding documentation.

Device to gateway encryption

Every single node in the network has its own private key (ensuring authenticity). Also, the gateway of the network (Meshlium) contains all nodes\' keys in order to decrypt the packets received from the nodes. The information goes encrypted from each node to the gateway so the intermediate nodes cannot access to it.

The process follows these steps:

  • Step 1: Create a new Frame (ASCII or BINARY)

  • Step 2: Encrypt the frame and use it as Encrypted Payload of the new Encrypted Frame

The function encryptFrame() is used to encrypt the original frame and generate the new one. It is necessary to indicate the type of AES encryption used regarding the key size: AES_128, AES_192 or AES_256. Besides, the AES private key must be specified as a string of ASCII characters.

Example of use:

{
    // 1. create the original frame
    frame.createFrame( ASCII );
    frame.addSensor( SENSOR_BAT, battery_level );
    
    // 2. create the AES-128 encrypted frame
    frame.encryptFrame( AES_128, "libeliumlibelium" );
    
    // 3. show Encrypted frame contained in \'frame.buffer\'
    frame.showFrame();
}

Example of how to use encryption with Waspmote Frames:

https://development.libelium.com/frame-07-encrypted-frames/

Regarding the Meshlium configuration (gateway of the network), please refer to the Meshlium Technical Guide. In the "Application layer key management" section, you can see how to set up the nodes' keys.

Device to Cloud encryption

This encryption mode is similar to the "Device to Gateway encryption" layer. However, instead of keeping the keys located in the gateway, they are stored in the Cloud. This allows to use different gateways (trusted or not trusted) as the information goes encrypted through them.

The encryptionToCloud() function allows the user to enable/disable the "Device to Cloud" encryption feature. This feature must be enabled before calling the encryptFrame() function. Basically, a different "frame type" is used in order to differentiate the "Device to Cloud" encryption mode from the "Device to Gateway" encryption mode. The frame structure is equal for the two encryption modes.

Therefore, the "Device to Cloud" encryption process follows these steps:

  • Step 1: Enable "Device to Cloud" encryption mode

  • Step 2: Create a new Frame (ASCII or BINARY)

  • Step 3: Encrypt the frame and use it as Encrypted Payload of the new Encrypted Frame

If the "Device to Cloud" encrypted frame is sent to Meshlium, it is stored inside the Meshlium database as it was received. It remains unencrypted. Then it should be sent to the Cloud server where the decryption process should be performed.

Fragment encryption

This section explains how to encrypt frame fragments. See the "Frame Fragments" section to understand how to fragment a original binary frame. The encryptFragment() function allows the user to encrypt the fragment currently stored in bufferFragment. This function needs two input parameters:

  • Encryption mode: AES_128, AES_192 or AES_256.

  • Password: AES encryption key to be used in encryption process.

The resulting encrypted fragment is stored in bufferFragment and lengthFragment. So the user shall send the encrypted data prior generating a new fragment.

Example of use:

{
    frame.createFrame(BINARY);
    frame.addSensor(SENSOR_STR, \"field 1\");
    frame.addSensor(SENSOR_STR, \"field 2\");
    ... // add numerous sensor fields into the original frame
    frame.addSensor(SENSOR_STR, \"field N\");
    // proceed to create fragments from the original binary frame
    // '80' is the maximum fragment size
    while (frame.createFragmentHeader(80) > 0)
    {
        // generate fragment
        frame.generateFragment();
        USB.println(F(\"Fragment frame:\"));
        USB.printHexln(frame.bufferFragment, frame.lengthFragment);
        // encrypt fragment
        frame.encryptFragment( AES_128, password);
        USB.print(F(\"Encrypted fragment frame:\"));
        USB.printHexln(frame.bufferFragment, frame.lengthFragment);
    }
}

Complete example:

https://development.libelium.com/frame-09-encrypt-frames/

Last updated