How to Quickly and Securely Connect IoT Applications to Google Cloud

By Stephen Evanczuk

Contributed By Digi-Key's North American Editors

Enterprise level cloud services such as Google Cloud offer IoT developers a wide array of capabilities ranging from scalable virtual machine services to turnkey artificial intelligence (AI) applications. A fundamental requirement for these services is the use of specific security methods for establishing and maintaining secure connections between IoT devices and the cloud. For developers, however, implementing appropriate security mechanisms can lead to delays and add complexity to design projects running on tight deadlines.

Built with a dedicated security IC, the PIC-IoT WG development board from Microchip Technology offers a turnkey solution to Google Cloud connectivity. Using a dedicated security IC, the kit provides a comprehensive platform designed to speed development of IoT designs able to connect securely to Google Cloud services. This article describes the key requirements for secure connectivity and shows how developers can meet those requirements using the PIC-IoT WG in a typical IoT design.

Security complexity

The ability to secure connections between IoT devices and remote host servers is fundamental to overall protection of IoT applications and related networked enterprise resources. These servers and other enterprise scale systems can provide capabilities and performance that are simply unavailable in IoT devices built with resource-limited microcontrollers and minimal memory. For simple IoT devices expected to deliver sensor data or operate actuators in a timely manner, the processing requirements alone for implementing even the most fundamental security algorithms can be prohibitive because of their nature.

Security methods rely on the basic principle that penetrating a security barrier should be more costly than the assets that the barrier is intended to protect. For algorithmic security methods, this means that deciphering an encrypted message or breaking an authentication protocol should be computationally prohibitive. At the very least, breaking algorithmic security should demand a level of computational resources and required time that exceed the value or timeliness of the protected data or communications channel. Consequently, cryptographic algorithms seek to bury valued data beneath a series of complex, computationally intensive processing steps involving a secret key. For example, the widely used Advanced Encryption Standard (AES) algorithm subjects data to multiple processing rounds, each comprising a series of steps starting with a secret key and continuing with byte substitutions, shifts, and matrix calculations (Figure 1).

Diagram of cryptographic algorithms purposely employ a series of complex manipulations

Figure 1: Intended to make decryption impractical and effectively impossible, cryptographic algorithms purposely employ a series of complex manipulations such as this step in the AES algorithm that combines data with bits derived from a private key. (Image source: Wikimedia Commons)

With symmetric cryptographic algorithms such as AES, receivers of an encrypted message use the same secret key to decrypt the data. In contrast, asymmetric algorithms use a pair of keys, one private and one public, eliminating the risks associated with use of a shared key at the cost of greater computational complexity. In this approach, a sender and receiver exchange public keys while keeping their own private keys secret. In turn, one party can use the other’s public key to encrypt a message that can be decrypted only with the other’s private key.

For further protection, advanced algorithms build on asymmetric public key cryptography methods to allow secure exchange of a short-lived shared private key used to encrypt data just for the duration of a particular message exchange session. Because of the critical nature of these key exchanges, more advanced algorithms such as elliptic curve Diffie-Hellman (ECDH) bury the secrets even deeper beneath complex elliptic curve calculations. Authentication protocols such as Transport Layer Security (TLS) combine mechanisms such as Diffie-Hellman key exchange with formal identification methods, using digital certificates that embed a public key with a verifiable digital signature from a certificate authority (CA) that attests to the certificate’s authenticity.

As this brief description suggests, security methods rely on layers of cryptographic algorithms and protocols that ultimately depend on private keys. Although these layers are subject to constant attack by hackers, the entire security structure will quickly collapse if the private keys can be discovered.

For this reason, hardware-based secure key storage is a fundamental requirement for IoT device security. Additionally, the computational complexity of these algorithms and protocols dictates the need for dedicated cryptography engines able to offload complex calculations from resource-limited microcontrollers.

Hardware-based security

Specialized secure element hardware devices such as the Microchip Technology ATECC608A CryptoAuthentication IC provide the features needed to protect secrets and accelerate execution of cryptographic algorithms. Among its features, the ATECC608A provides an on-chip EEPROM for secure storage of up to 16 keys, certificates, and other data as well as other necessary capabilities including a NIST SP 800-90A/B/C-compliant random number generator.

As well as being a secure storage device, the ATECC608A can accelerate execution of a number of algorithms including AES for symmetric cryptography and ECDH for asymmetric cryptography. The device also provides support for higher level services including secure boot (see, “Use a Crypto Chip to Add Secure Boot to IoT Device Designs”).

In addition to the direct performance benefits obtained from offloading the execution of these algorithms, the ATECC608A’s integration of these crypto engines, secure storage, and other features inherently provides another layer of security: keys remain isolated from untrusted entities. These entities include microcontrollers not designed for security, software running on the microcontroller, and individuals using the software. The device’s ability to generate private keys provides further security during provisioning in manufacturing or distribution facilities.

The result is a reduction in the number of threat vectors, compared to conventional software-based security methods. This supports the kind of defense-in-depth that lies at the heart of effective security policies.

This comprehensive integration of functionality in the ATECC608A simplifies hardware interface requirements. The device operates as another I2C peripheral that can even share a microcontroller’s I2C bus with other devices, such as digital sensors like Microchip Technology’s MCP9808 (Figure 2).

Diagram of Microchip Technology ATECC608A CryptoAuthentication IC

Figure 2: Because the Microchip Technology ATECC608A CryptoAuthentication IC (left) completes its security processing entirely on chip, it can provide a simple I2C hardware interface for use with other I2C devices such as Microchip Technology’s MCP9808 I2C digital temperature sensor (right). (Image source: Microchip Technology)

At the software level, however, the ATECC608A’s extensive functionality results in a more complex interface. Microchip Technology’s CryptoAuthLib library abstracts this interface into a set of intuitive function calls available in the CryptoAuthLib application programming interface (API). This library is bundled with related drivers and middleware in Microchip Technology’s MPLAB X Integrated Development Environment (IDE). Although the CryptoAuthLib API and drivers provide the foundational elements for custom designs with the ATECC608A, developers face additional challenges in implementing the full security chain required for secure connectivity with Google Cloud. Microchip Technology’s PIC-IoT WG development board removes that hurdle as well.

Developing an end-to-end IoT application

Based on the ATECC608A and Microchip Technology’s low-cost PIC24FJ128GA705 16-bit microcontroller, the PIC-IoT board is a wireless IoT design that includes the Microchip Technology ATWINC1510 Wi-Fi module, Vishay Semiconductor’s TEMT6000X01 ambient light sensor, and the MCP9808 I2C temperature sensor. In addition, developers can easily extend the hardware base platform by adding sensors and actuators provided with the hundreds of available MikroElektronika Click boards. For software development, Microchip Technology provides its MPLAB X IDE and associated MPLAB Code Configurator (MCC) rapid prototyping tool.

The board and related software provide a turnkey platform for evaluating a basic end-to-end IoT application running from the IoT sensor device to Google Cloud services over secure connections. The kit implements a unique approach designed to enable mutual authentication, even with resource-constrained IoT devices. In this approach, the IoT device can use lightweight TLS services to authenticate the Google side of the connection and JavaScript Object Notation (JSON) Web Tokens (JWT) to authenticate themselves to the Google servers (see, “An Easier Solution for Securely Connecting IoT Devices to the Cloud”). Along with device drivers, board support packages, and middleware services, Microchip Technology demonstrates this approach as part of a complete sample IoT application available for the PIC-IoT board through the MPLAB development suite.

Working through the sample application developers can gain experience working not only with cloud applications, but also with IoT-specific services provided by major cloud service providers for connecting IoT devices to their cloud. For example, IoT devices access Google Cloud resources through Google Cloud IoT Core, which provides a range of services needed to connect those devices, manage their related metadata, and more (Figure 3).

Diagram of Google Cloud provides a specialized service offering, Google Cloud IoT Core

Figure 3: As with other enterprise cloud providers, Google Cloud provides a specialized service offering, Google Cloud IoT Core, designed to support the unique requirements associated with integrating IoT devices with cloud resources. (Image source: Google)

Using cloud services

On the back end, Google Cloud IoT Core provides devices with access to high-level Google Cloud resources through a data broker using a publication/subscription (pub/sub) model. On the front end, the IoT Core provides a bridge that supports IoT device connectivity using Hypertext Transfer Protocol (HTTP) or Message Queuing Telemetry Transport (MQTT). MQTT is an International Organization for Standardization (ISO) standard messaging transport designed to run with minimal communications bandwidth and IoT devices’ resources. Microchip Technology’s software application for the PIC-IoT board demonstrates use of MQTT running on a Transmission Control Protocol/Internet Protocol (TCP/IP) socket connection that is secured with the TLS/JWT mutual authentication method described earlier.

After establishing the secure connection, the software uses MQTT to communicate with Google Cloud IoT Core services for establishing a channel, or “topic”, used to send sensor data to the Google Cloud and respond to commands from cloud services. Google calls for IoT device software to subscribe and subsequently send data to a designated topic of the form /devices/{deviceID}/events and provides the option for subtopics under the broad events topic. In addition to other topics such as those for device management features, Google designates a topic /devices/{device-id}/commands for sending commands from the cloud to the IoT device. Google even provides a catch-all topic (/devices/{device-id}/commands/#) that allows IoT devices to receive commands sent through any subtopic.

The PIC-IoT application demonstrates these various procedures using an extensible software architecture based on timers and callbacks. Because of this architecture, the main module (main.c) only needs to provide the main routine (main()) as well as application-level routines for sending (sendToCloud()) and receiving (receivedFromCloud()) messages. The main() routine itself just calls a pair of initialization routines before entering an endless loop that runs the timer scheduler and provides a placeholder for user routines (Listing 1).

Copy
void receivedFromCloud(uint8_t *topic, uint8_t *payload)
{
    char *toggleToken = "\"toggle\":";
    char *subString;
    
    if ((subString = strstr((char*)payload, toggleToken)))
    {
        LED_holdYellowOn( subString[strlen(toggleToken)] == '1' );
    }
 
 
    debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "topic: %s", topic);
    debug_printer(SEVERITY_NONE, LEVEL_NORMAL, "payload: %s", payload);
}
 
// This will get called every 1 second only while we have a valid Cloud connection
void sendToCloud(void)
{
   static char json[70];
         
   // This part runs every CFG_SEND_INTERVAL seconds
   int rawTemperature = SENSORS_getTempValue();
   int light = SENSORS_getLightValue();
   int len = sprintf(json, "{\"Light\":%d,\"Temp\":\"%d.%02d\"}", light,rawTemperature/100,abs(rawTemperature)%100);
 
   if (len >0) {
      CLOUD_publishData((uint8_t*)json, len);
      LED_flashYellow();
   }
}
 
#include "mcc_generated_files/application_manager.h"
 
/*
                         Main application
 */
int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    application_init();
 
    while (1)
    {
        // Add your application code
        runScheduler();
    }
 
    return 1;
}

Listing 1: The Microchip Technology sample application for the PIC-IoT board uses a series of timers and callbacks that simplifies the main loop and allows developers to easily add their own services and application routines. (Code source: Microchip Technology)

Called prior to the endless loop, the SYSTEM_Initialize() routine initializes hardware components including the clock, analog-to-digital converter (ADC), interrupts, and others. The application_init() routine initializes various software systems including the CryptoAuthentication library, connects to Wi-Fi, and to the cloud itself. As its last task, application_init() sets a 100 millisecond (ms) timer for execution of the MAIN_dataTask(). When the timer expires and MAIN_dataTask() is invoked, it checks the cloud connection and calls sendToCloud() once per second, setting the board’s LEDs as appropriate to indicate the application’s current operating status (Listing 2). In turn, developers can view a display of sensor values on a free sandbox account provided by Microchip Technology on Google Cloud.

Copy
// This gets called by the scheduler approximately every 100ms
uint32_t MAIN_dataTask(void *payload)
{
   static time_t previousTransmissionTime = 0;
   
   // Get the current time. This uses the C standard library time functions
   time_t timeNow = time(NULL);
   
   // Example of how to send data when MQTT is connected every 1 second based on the system clock
   if (CLOUD_isConnected())
   {
      // How many seconds since the last time this loop ran?
      int32_t delta = difftime(timeNow,previousTransmissionTime);
   
      if (delta >= CFG_SEND_INTERVAL)
      {
         previousTransmissionTime = timeNow;
         
         // Call the data task in main.c
         sendToCloud();
      }
   } 
 
    if(shared_networking_params.haveAPConnection)
    {
        LED_BLUE_SetLow();
    }
    else
    {
        LED_BLUE_SetHigh();
    }
    if(shared_networking_params.haveERROR)
    {
        LED_RED_SetLow();
    }
    else
    {
        LED_RED_SetHigh();
    }
    if (LED_isBlinkingGreen() == false)
    {
        if(CLOUD_isConnected())
        {
            LED_GREEN_SetLow();
        }
        else
        {
            LED_GREEN_SetHigh();
        }
    }
   
   // This is milliseconds managed by the RTC and the scheduler, this return makes the
   //      timer run another time, returning 0 will make it stop
   return MAIN_DATATASK_INTERVAL; 
}

Listing 2: Using a timer and callback mechanism, Microchip Technology’s PIC-IoT sample application sends sensor data to the cloud once per second (CFG_SEND_INTERVAL=1) and updates the board’s LEDs to indicate the current operating state. (Code source: Microchip Technology)

Processing commands from the cloud is just as easy. The sample application demonstrates how to associate a callback routine such as receivedFromCloud() for handling received messages. As part of the initialization phase, the application_init() routine mentioned earlier calls a routine (CLOUD_subscribe()) that performs the Google Cloud subscription process. As part of this process, the software updates a table (imqtt_publishReceiveCallBackTable) with the callback to receivedFromCloud() (Listing 3). In this case, the sample application uses the config topic and hardcodes the index into the table since NUM_TOPICS_SUBSCRIBE=1, but the more general commands topic and derived subtopics are another option.

Copy
void CLOUD_subscribe(void)
{
   mqttSubscribePacket cloudSubscribePacket;
   uint8_t topicCount = 0;
 
   // Variable header
   cloudSubscribePacket.packetIdentifierLSB = 1;
   cloudSubscribePacket.packetIdentifierMSB = 0;
 
   // Payload
   for(topicCount = 0; topicCount < NUM_TOPICS_SUBSCRIBE; topicCount++)
   {
      sprintf(mqttSubscribeTopic, "/devices/%s/config", deviceId);
      cloudSubscribePacket.subscribePayload[topicCount].topic = (uint8_t *)mqttSubscribeTopic;
      cloudSubscribePacket.subscribePayload[topicCount].topicLength = strlen(mqttSubscribeTopic);
      cloudSubscribePacket.subscribePayload[topicCount].requestedQoS = 0;
 
      imqtt_publishReceiveCallBackTable[0].topic = mqttSubscribeTopic;
      imqtt_publishReceiveCallBackTable[0].mqttHandlePublishDataCallBack = receivedFromCloud;
      MQTT_SetPublishReceptionHandlerTable(imqtt_publishReceiveCallBackTable);
   }
   
   if(MQTT_CreateSubscribePacket(&cloudSubscribePacket) == true)
   {
      debug_printInfo("CLOUD: SUBSCRIBE packet created");
      sendSubscribe = false;
   }
}

Listing 3: The Microchip Technology sample applications shows how developers can easily associate callback routines with received MQTT messages, in this case defining the receivedFromCloud() function as the callback for received messages from the default topic. (Code source: Microchip Technology)

Developers can use the PIC-IoT hardware and software bundle as delivered to begin immediately exploring different scenarios for sending and receiving data from the Google Cloud. The PIC-IoT hardware including the ATECC608A CryptoAuthentication device are preconfigured to support the Google Cloud IoT Core and this use model. Developers can easily use the MPLAB X IDE and MPLAB Code Configurator to modify or build an entirely new IoT application designed to connect securely to the Google Cloud.

Conclusion

Providing secure connections between IoT devices and networked resources is essential for any networked service environment and mandatory for working with commercial cloud services. Building the layers of software services required for secure connectivity can add significant delays to IoT projects and can even be impractical in resource-constrained IoT designs. Using a development board such as the Microchip Technology PIC-IoT, which includes a specialized security IC, developers can quickly bring up an IoT application able to connect securely to Google Cloud.

Disclaimer: The opinions, beliefs, and viewpoints expressed by the various authors and/or forum participants on this website do not necessarily reflect the opinions, beliefs, and viewpoints of Digi-Key Electronics or official policies of Digi-Key Electronics.

About this author

Stephen Evanczuk

Stephen Evanczuk has more than 20 years of experience writing for and about the electronics industry on a wide range of topics including hardware, software, systems, and applications including the IoT. He received his Ph.D. in neuroscience on neuronal networks and worked in the aerospace industry on massively distributed secure systems and algorithm acceleration methods. Currently, when he's not writing articles on technology and engineering, he's working on applications of deep learning to recognition and recommendation systems.

About this publisher

Digi-Key's North American Editors