Hashes are a very important topic in computer science and provide a wide range of capabilities and functionality. To an embedded software developer, hashes play an important role in verification and securing an embedded system. In this post, we will examine cryptographic hash fundamentals and provide the foundations that a developer can use to start understanding embedded security.
Let’s start by looking at the very definition of a hash. A hash, is a value that is generated by a hash function based on the input provided to the function. The hash is used to provide a value that can be used to verify the integrity of information without revealing that information to the party performing the verification. For example, a developer can run their software image through a hash function to generate a hash value that can be used by a customer or end-user to verify that they received the correct software image.
A developer should consider a hash to be a unique digital fingerprint of the data. The nice thing about the hash function is that an end-user can verify that they have the correct software by comparing their hash with the officially generated hash but the hash value cannot be used to generate the information. The process is meant to be unidirectional. This provides a simple method to verify without giving away the details.
There are several different hash functions that are used to generate hashes, which are also sometimes called hash codes or hash values. A few common hashes include:
When a hash is generated, a fixed number of output bits are generated for the input data. For example, a commonly used cryptographic hash, SHA-1 (Secure Hash Algorithm 1), produces a 160-bit value. A developer can generate a SHA-1 hash by feeding their data into their SHA-1 generator or even use an online generator to experiment. Simple data such as “Hello World!” generates the hash below:
SHA-1(“Hello World!”) = 2ef7bde608ce5404e97d5f042f95f89f1c232871
Hashes play several different roles in an embedded. First, a hash can be used by a bootloader to verify that the software image they have received is indeed correct the image. Second, hashes can be used as part of a secure boot sequence to verify firmware image integrity during boot-up. If a hacker has tried to inject their own code into the application image, the stored hash will not match the application that is stored in flash and signal that something is not right with the application. Third, hashes play a role in server authentication and digital-signing.
Embedded software developers need to be careful when selecting the hash algorithm that they are going to be using in their application. Hash functions can be compute cycle intensive, which means that they could take a while to calculate on a resource restrained device such as a microcontroller. There are several considerations that developers should think through before settling on a hash function:
- identify whether there is a hardware accelerator on their microcontroller that can speed up hash calculations
- evaluate which algorithm best fits their application. (There is no need to use SHA3-512 if SHA-1 will be sufficient
Before embedded developers realize it, hashes will be far more pervasive in embedded systems than CRC’s and checksums. In fact, in some areas they may already be! They’ve already been used for years in general computing systems and as security becomes a major concern in many connected systems, it’s only natural that they find their way into microcontroller based systems as well.