Hashes are crucial in computer science and provide a wide range of capabilities and functionality. In addition, hashes play an important role in verifying and securing an embedded system to an embedded software developer. This post 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 generated by a hash function based on the input provided to the function. The hash is used to provide a value that can verify the integrity of information without revealing that information to the party performing the verification. So, for example, a developer can run their software image through a hash function to generate a hash value that a customer or end-user can verify that they received the correct software image.
A developer should consider a hash a unique digital fingerprint of the data. The hash function’s nice thing is that end-users can verify that they have the correct software by comparing their hash with the officially generated hash. Still, 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.
Several different hash functions are used to generate hashes, sometimes called hash codes or hash values. A few common hashes include:
A fixed number of output bits are generated when a hash is 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 an SHA-1 hash by feeding their data into their SHA-1 generator or experimenting with an online generator. For example, 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 bootloader can use a hash to verify that the software image they have received is indeed correct. Second, hashes can be used as part of a secure boot sequence to verify firmware image integrity during boot-up. Third, if a hacker has tried to inject their own code into the application image, the stored hash will not match the application 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 they will be using in their application. Hash functions can be computed 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 is sufficient
Before embedded developers realize it, hashes will be far more pervasive in embedded systems than CRCs and checksums. In fact, in some areas, they may already be! But, of course, they’ve already been used for years in general computing systems. 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.