Embedded and Firmware Security

Firmware, kernel and driver security testing for embedded devices and Linux platforms. This includes embedded device and firmware testing, binary analysis and reverse engineering, Linux platform and kernel reviews, and cryptographic evaluation. nandsec works with or without source code, and also accepts bespoke hardware and firmware requests.

checksum.csource
uint32_t checksum(const uint8_t *buf, size_t len)
{
uint32_t sum = 0;
for (size_t i = 0; i < len; i++)
sum += buf[i];
return sum;
}
compile
checksum.s · x86-64gcc -O1
checksum:
test rsi, rsi
je .L4
mov rax, rdi
add rdi, rsi
mov edx, 0
.L3:
movzx ecx, BYTE PTR [rax]
add edx, ecx
add rax, 1
cmp rax, rdi
jne .L3
.L1:
mov eax, edx
ret
.L4:
mov edx, 0
jmp .L1
decompile
Ghidra decompiler (GUI)recovered C
int checksum(byte *param_1, long param_2)
{
byte *pbVar1;
int iVar2;
if (param_2 == 0) {
return 0;
}
pbVar1 = param_1;
iVar2 = 0;
do {
iVar2 = iVar2 + (uint)*pbVar1;
pbVar1 = pbVar1 + 1;
} while (pbVar1 != param_1 + param_2);
return iVar2;
}
$ gcc -O1 -S -masm=intel -fno-asynchronous-unwind-tables checksum.c # function body of checksum.s

loop body One byte is zero-extended and added to the running total.

Embedded device and firmware testing

Embedded device and firmware testing covers the board, the firmware and every interface a device exposes, including UART, JTAG and SWD debug ports. nandsec dumps the SPI flash, extracts and unpacks the firmware, and analyses its root filesystem, boot verification and update signing.

Test coverage

  • Debug interfaces such as UART, JTAG and SWD
  • Firmware extraction, unpacking and analysis
  • Boot verification and firmware updates
  • Network services, mobile apps and cloud APIs the device uses

How it runs

We test production units of the device and confirm each finding on the hardware.

kernel.uimg · offset 0x00hexdump -C
0000000001101101110001101101000100000101|'..V....e/.@.;*.|
0000001000111011001111011011000100101011|.........A.}....|
0000002011011111011111110100110010011111|Linux-5.15.0-nan|
0000003000011100111010011100100101001111|dsec-demo.......|
0x00magic0x27051956
0x04header CRC0x1214E61C
0x08timestamp2023-10-18 07:50:24 UTC
0x0cdata size3,877,392 bytes
0x10load address0x80008000
0x14entry point0x80008000
0x18data CRC0x9C41E27D
0x1cOS5 · Linux
0x1darch2 · ARM
0x1etype2 · kernel
0x1fcompression0 · none
0x20name"Linux-5.15.0-nandsec-demo"

magic: Identifies a U-Boot legacy image. Parsers should reject images without it.

Binary analysis and reverse engineering

Binary analysis and reverse engineering examines compiled software and firmware when no source code is available. Examples are a supplier's firmware or a third-party agent you plan to deploy. nandsec disassembles and decompiles each target, then audits its protocols, file parsers, licence checks and update logic for hard-coded keys and memory corruption.

Analysis scope

  • Network protocols and file formats
  • Authentication, licensing and update logic
  • Hard-coded credentials and keys
  • Memory safety in parsers and handlers

How it runs

We reverse engineer only with the authorisation of the owner or licensee and within the Copyright Act 1968 (Cth).

Linux platform security review

Linux platform security review assesses how a Linux image, appliance or server is built and locked down, from the bootloader to its running services. nandsec verifies the Secure Boot chain, TPM 2.0 measured boot, kernel lockdown, module signing and the SELinux or AppArmor policy. The core focus is on providing correctly configured and hardened Linux environments.

Review scope

  • Secure Boot, signed images and key handling
  • Measured boot with TPM 2.0 and disk encryption
  • Kernel configuration, lockdown and module signing
  • SELinux or AppArmor policy and service privileges

How it runs

We review the build configuration and test a running image.

Secure Boot
Passes
Every stage verifies the next one before running it.
Measured boot (TPM 2.0, PCRs 0, 4, 7, 9)
Disk unlocks
PCR values match the policy the disk key was sealed against. PCR 7 records the Secure Boot state and the enrolled keys.

Kernel and driver security review

Kernel and driver security review examines kernel modules and drivers for memory safety bugs, including use-after-free, double fetch and unchecked user pointers in ioctl handlers. nandsec audits the source, fuzzes each interface and reproduces every finding with proof-of-concept code shared only with your team.

Review scope

  • System call and ioctl handlers
  • Memory handling, reference counting and locking
  • Data copied between user space and the kernel
  • Rust and C code at the boundary between them

How it runs

We review the source and share proof-of-concept code with your team only.

drivers/misc/demo.cioctl handler
static long demo_ioctl(struct file *f, unsigned int cmd,
unsigned long arg)
{
struct demo_dev *dev = f->private_data;
struct demo_req req; // { __u32 len; __u64 data; }
long ret = 0;
if (cmd != DEMO_IOC_SET)
return -ENOTTY;
if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
return -EFAULT;
if (req.len > sizeof(dev->buf)) // the length check
return -EINVAL;
mutex_lock(&dev->lock);
if (copy_from_user(dev->buf, u64_to_user_ptr(req.data), req.len))
ret = -EFAULT;
mutex_unlock(&dev->lock);
return ret;
}
calls from user spacereturn value / dmesg
ioctl(fd, SET, len=16)0
ioctl(fd, SET, len=64)0
ioctl(fd, SET, len=128)0
ioctl(fd, SET, len=255)0
ioctl(fd, SET, len=256)0
ioctl(fd, SET, len=257)-EINVAL
ioctl(fd, SET, len=512)-EINVAL
ioctl(fd, SET, len=4096)-EINVAL

buf is a 256-byte array Requests longer than the buffer are refused before the copy. The caller controls len, so the driver must not trust it.

Cryptographic implementation review

The objective of a cryptographic evaluation and review is to find where your product's cryptography can fail, from key generation to protocol design. nandsec reviews the source and tests each path for nonce reuse, weak key storage, downgrade attacks and non-constant-time comparisons.

Review scope

  • Key generation, storage and rotation
  • Randomness and nonce handling
  • Protocol design and library use
  • Constant-time behaviour in sensitive comparisons

How it runs

We review the source and help plan protocol changes for devices already in the field.

samples per guess (local): 2,000
compare.c · early exit, vulnerableC
for (i = 0; i < n; i++)
if (a[i] != b[i])
return 0; // exits at the first mismatch
return 1;

guess k stands out A correct first byte adds one loop iteration. With enough samples the difference is measurable, and each following byte can be recovered the same way.

Other services

Penetration TestingApplications, APIs, cloud, networks and internet-facing systems. Security Architecture and AdvisoryThreat models, architecture review and secure design. AI and Agent SecuritySecure setup, review and testing for AI tools, agents and AI-built software. Red Teaming and ForensicsRed and purple team engagements, compromise assessment and malware analysis. Security EngineeringHardened systems, secure pipelines and secure firmware for your products. Software Design and EngineeringArchitecture, full-stack, mobile and systems development. Applied ResearchSecurity research across operating systems, memory safety, malware, firmware and AI agents.

Scope a test

Email [email protected] with the product, the hardware revision and whether source code is available. We reply with a scoping outline and the number of units we need. For sensitive discussions, or if you prefer, message us on Signal or SimpleX.