To prevent counterfeit devices from joining a network or to limit the opportunity for network attacks, it’s important to authenticate devices attempting to join Internet of Things (IoT) networks and subsequently connect only authorized devices. The standard mechanism to securely authenticate clients connecting to a server is transport-layer-security (TLS) client-side authentication.
To implement such authentication in an IoT network, the appropriate certificate authority (CA)—usually the IoT device provider—issues a unique X.509 certificate to each IoT device and the associated private key that functions as a unique security credential for the IoT device. Once the certificate and associated private key are stored on the IoT device, it may use them during the TLS client-authentication process to securely join the IoT network.
The act of supplying the necessary credentials to a device joining a network is known as “provisioning.” It’s important to have a user-transparent provisioning process in order to minimize onboarding challenges or security lapses. Therefore “zero-touch provisioning,” which eliminates the need for any user interaction, is highly desired in IoT applications.
A common but challenging certificate provisioning approach is to physically add CA-issued credentials to devices during manufacturing. Since it’s critical to prevent unauthorized parties from learning the values of private keys, manufacturing processes that involve the management of private keys must be highly secure and completely trustworthy. Such a requirement rules out many—if not all—low-cost contract manufacturers. But the need to keep many classes of IoT devices low cost requires approaches that entail using these types of manufacturers.
One provisioning process that has gained traction is pre-populating “secure elements” with certificates at a secure location and then shipping the secure elements to a low-cost manufacturer, which assembles the complete IoT device. Secure elements are chips that provide hardware-based cryptoaccelerators and secure key storage, sometimes augmented with additional protections against hardware tampering and side channel attacks. A number of companies, such as semiconductor distributors, now offer specific services to program secure elements with certificates in a trustworthy environment.
While pre-populating secure elements with certificates enables the use of low-cost manufacturers without compromising security, this approach obviously adds to product and manufacturing cost. The secure element adds to the bill of materials (BOM), and then pre-populating the certificate is an additional manufacturing step that requires a trustworthy (and high cost) environment.
In this article, I’ll discuss an implementation based on a Texas Instruments SimpleLink Wi-Fi microcontroller (MCU) and Amazon Web Services (AWS) that provisions certificates at run time and eliminates the need to pre-populate certificates during manufacturing. SimpleLink Wi-Fi MCUs include on-chip capabilities that are equivalent to an external secure-element chip, such as secure key and certificate storage, a pre-burned unique device identity (UDID), a pre-burned public/private key pair, and cryptographic acceleration. As a result, this implementation doesn’t require a secure element. However, it’s also easy to duplicate the approach described in this article using an MCU combined with a discrete secure element.
AWS provides a broad array of generic compute services and specific software-as-a-service (SaaS) offerings such as databases and analytics. I will discuss the use of a few AWS services, including API Gateway, Lambda, and Amazon Certificate Manager, to create a zero-touch provisioning service for IoT devices connecting to AWS IoT Core.
Run-Time Provisioning of Certificates
Any internet-connected device (or server) may use a certificate signing request (CSR) as a request to a certificate authority (CA) for an X.509 certificate. The device can then present this certificate when client authentication is required. The CSR provides a mechanism for an IoT device to obtain a certificate at run time, typically during installation at the user’s premises, which eliminates the need to pre-populate certificates during manufacturing. Since the IoT device would be programmed to issue the CSR upon first connection, this approach can provide zero-touch provisioning and thus be invisible to end users.
To generate a CSR, the IoT device fills the appropriate fields to create an X.509 certificate, such as the business or organization name and its location. The CSR must contain a public key and a digital signature created by encrypting a hash of the CSR with the associated private key.
Although the key pairs used in most CSRs are typically generated for use in a secure provisioning implementation for IoT devices, it’s more preferable for the original equipment manufacturer (OEM) to embed the key pair into the device before shipping to a customer, either by using an MCU with pre-burnt keys or by adding a secure element. Since there’s no need to pre-program the secure element with the certificate, the manufacturing process no longer requires this step.
The reason why the IoT device can’t generate the key pair is to prevent unauthorized devices from obtaining a certificate that would enable them to join the IoT network. In isolation, a CA will fulfill any CSR request that uses a valid public/private key pair. To prevent this, a provisioning process must screen all CSR requests to ensure that they come from a device authorized to join the network. For example, the provisioning process could entail checking the public key in the CSR against a list of public keys contained in IoT devices shipped by the OEM, which effectively implements a whitelisting mechanism.
A similar approach might use a UDID to authorize the CSR completion. The UDID might be pre-burnt into the device or entered using a mobile application that scans a bar or QR code. Using a combination of both the UDID and public key enhances security, as an attacker would need to obtain two values rather than one value to compromise the system.
Implementing a CSR-Based Provisioning Mechanism for IoT devices
AWS IoT Core is a cloud-based IoT service that uses Message Queue Telemetry Transport (MQTT) communication over a secure TLS socket to provide services such as device management, telemetry, and remote updates. To perform client authentication, TLS requires that the IoT device possess a certificate. Since a SimpleLink Wi-Fi device includes a pre-burned key pair and a pre-burned UDID, as well as the ability to generate a CSR, TI and AWS used these capabilities to implement a run-time provisioning solution. This solution enables a SimpleLink Wi-FI-based IoT device to obtain a certificate before connecting to the main AWS IoT Core.
Let’s review this implementation in more detail, beginning with the embedded side. A SimpleLink Wi-Fi device includes a separate network processor with read-only memory (ROM) code that implements wireless networking, secure storage, and cryptographic operations. The ROM wireless-network functions include CSR generation.
Figure 1 illustrates the steps on the IoT device. The first time the device boots, it will check whether or not it has the client certificate. If not, it will begin the provisioning process. The first step is to generate the CSR. In addition to filling out location, organization name, and signing algorithm information, the IoT device will include the pre-burnt public key in the CSR, enter the UDID into the certificate’s name field, and then create a hash of the certificate and encrypt it using its private key to create the digital signature to sign the CSR.
The IoT device will next connect to the provisioning service through a TLS connection, which will only require server-side authentication. The device manufacturer will need to include the URL of the provisioning server, along with the trusted root required to validate the server certificate chain, in the standard image programmed into each IoT device. Once connected to the provisioning service, the IoT device sends the CSR request. If the provisioning service successfully authorizes the IoT device to join, it will send the client certificate to the device. The IoT device must then store the certificate securely to prevent unauthorized access.
A SimpleLink Wi-Fi device has a secure file system that enables the storage of code and data in encrypted flash. MCUs lacking a similar capability can use a discrete secure element. At this point, the IoT device is able to connect to AWS IoT Core and present the certificate during the client authentication step.
On the cloud side, the main AWS services used (Fig. 2) are Amazon API Gateway, AWS Lambda, and Amazon Certificate Manager (ACM) Private CA. The provisioning implementation must also register certificates issued to an IoT device to AWS IoT Core. The public key infrastructure (PKI) administrator responsible for the CA that issues the device certificates must also register the CA certificate—typically an immediate root certificate—with AWS IoT Core. To enhance security, AWS IoT Core only connects devices with certificates issued by a registered CA.
Amazon API Gateway provides a representational state transfer (REST) interface (such as Hypertext Transfer Protocol (http)) for the IoT device to initially connect to and then begin the provisioning process. AWS Lambda runs the two core functions of the provisioning service: authorization and certificate issuance. The implementation uses AWS Lambda because the functions only run in response to an IoT device contacting the provisioning service. As a result, maintaining a permanent server would be expensive. AWS Lambda provides a serverless, event-driven execution model that best meets the application requirements while minimizing cloud-computing costs.
The first function that runs after the IoT device contacts the Amazon API Gateway is the authorization function. The authorization function extracts the UDID and public key from the certificate and compares both to values in a pre-populated database—shown as the public key table in Figure 2.
Although it’s possible to implement the public key table in a variety of formats, the example implementation uses the AWS DynamoDB service, which is a relational database. AWS DynamoDB uses the UDID as an index to retrieve a public key from the database and then compares this key against the one in the certificate. If they match, the function authorizes the CSR operation to proceed
A second AWS Lambda function fulfills the CSR and issues the certificate obtained from ACM Private CA, which provides a link to import certificates from the IoT device provider’s CA and forwards the certificate to the device itself via the Amazon API Gateway interface. The issuer function also registers the certificate in AWS IoT Core and creates the thing to represent the device, along with the appropriate policy.
This flow addresses the delivery of the certificate to IoT devices when they’re customer-ready. An alternate flow uses AWS IoT Core to issue the certificates. That flow is primarily meant for development, as it eliminates the need to immediately integrate ACM Private CA with the IoT device provider’s CA. Certificates issued by AWS IoT Core are only valid for the specific AWS region that issues them, and therefore not suitable if the intent is to deploy a product worldwide.
Creating the Public Key Table
An additional out-of-band step required to implement the provisioning flow is populating the database used to authorize CSR requests. This step requires obtaining the UDID and public key values from the MCU or secure element used in each IoT device. In some cases, these values will be available in whitelists provided by the semiconductor supplier.
However, such whitelists are often tied to minimum quantity purchases (typically around 2,000 units) related to the size of reels in the semiconductor manufacturing process. As a result, during initial development and testing of an IoT device, it’s necessary to extract this information programmatically, since any volume purchases of MCUs or secure elements generally occur later during production ramps.
For the SimpleLink Wi-FI MCU, Texas Instruments designed the flow shown in Figure 3 so that developers could extract the UDID and public key for subsequent uploading to the cloud. A developer connects the IoT device to TI’s Uniflash tool via a Universal Asynchronous Receiver Transmitter (UART) connection. In this mode, a SimpleLink Wi-Fi-based device boots up and then provides a hook in the boot process for Uniflash to download a function. The developer then downloads a pre-provided function that reads out the UDID and public key.
This method enables the IoT device provider to populate the database at any point in the development and production process, regardless of semiconductor volume purchases. An important aspect of this approach is the temporary download of the extraction function, which eliminates the need to both incorporate the function into the primary MCU image and add the associated logic to activate it only under specific circumstances.
Client-side authentication is important to IoT device providers to prevent IoT device clones from joining the network as well as to strengthen security. Adding security credentials during manufacturing raises costs, as it requires either a secure manufacturing environment or the purchase of secure elements with pre-populated credentials. An alternative approach is to download the credential when the device first connects to the network.
This article presented a technical overview of a run-time provisioning implementation based on TI SimpleLink Wi-Fi and AWS IoT Core that uses CSR to obtain the security credentials, combined with an additional authorization service that checks a UDID/public key combination to block CSRs from unauthorized devices.
For further details of this run-time provisioning implementation, see https://github.com/aws-samples/iot-provisioning-secretfree for the AWS cloud-side code and documentation (including code for creating the public key table in AWS DynamoDB), and dev.ti.com/CC32XX_AWS_PKT_provisioning for the SimpleLink SDK embedded-side code and documentation.
I would like to thank Richard Elberger, senior applications engineer at AWS, and Kobi Leibovitch, SimpleLink applications engineer at Texas Instruments, for sharing their knowledge of the provisioning software implementation.
Nick Lethaby is IoT Ecosystem Manager at Texas Instruments.