cryptnox-sdk-arduino 1.0.0
Arduino library for Cryptnox Hardware Wallet
Loading...
Searching...
No Matches
fuzz_der.cpp
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: LGPL-3.0-or-later
3 * Copyright (c) 2026 Cryptnox SA
4 */
5
6/*
7 * fuzz_der.cpp — libFuzzer harness for the two DER parser paths in
8 * CW_SecureChannel (SEC-015).
9 *
10 * Targets:
11 * derWalkMfCert() file-static DER X.509 cert walker
12 * CW_SecureChannel::parseDerSigToRaw() private-static DER sig parser
13 *
14 * Build (Linux / macOS, clang required):
15 * cd cryptnox-sdk-cpp/fuzz
16 * mkdir build && cd build
17 * cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
18 * make
19 *
20 * Run:
21 * ./fuzz_der corpus/ -max_len=512 -jobs=4
22 *
23 * Corpus seeds:
24 * Place valid DER ECDSA signatures and manufacturer certificate blobs
25 * inside corpus/. See corpus/README.md for instructions.
26 *
27 * Input format (first byte selects target):
28 * 0x00 + <bytes> → parseDerSigToRaw only
29 * 0x01 + <bytes> → derWalkMfCert only
30 * anything else → both parsers receive the same payload
31 */
32
33/* Must be defined before including CW_SecureChannel.h so the friend
34 * declaration for DerFuzzTarget is compiled in. */
35#define CW_FUZZ_BUILD 1
36
37#include <stdint.h>
38#include <stddef.h>
39#include <string.h>
40
41/* ── SDK headers ────────────────────────────────────────────────────── */
43#include "../CW_NfcTransport.h"
44#include "../CW_Logger.h"
45#include "../CW_Platform.h"
46#include "../CW_SecureChannel.h"
47
48/* ── Minimal concrete stubs for the three abstract interfaces ──────────
49 * Required so CW_SecureChannel.cpp compiles; these methods are never
50 * reached from the DER-parser call paths exercised by this harness. */
51
52class StubNfc final : public CW_NfcTransport {
53public:
54 bool begin() override { return false; }
55 bool inListPassiveTarget() override { return false; }
56 bool sendAPDU(const uint8_t*, uint8_t,
57 uint8_t*, uint8_t&) override { return false; }
58 void resetReader() override {}
59 bool printFirmwareVersion() override { return false; }
60};
61
62class StubLogger final : public CW_Logger {
63public:
64 bool begin(unsigned long) override { return true; }
65 void print(const __FlashStringHelper*) override {}
66 void print(const char*) override {}
67 void print(char) override {}
68 void print(uint8_t, int) override {}
69 void print(uint16_t, int) override {}
70 void print(uint32_t, int) override {}
71 void print(int, int) override {}
72 void println() override {}
73 void println(const __FlashStringHelper*) override {}
74 void println(const char*) override {}
75 void println(char) override {}
76 void println(uint8_t, int) override {}
77 void println(uint16_t, int) override {}
78 void println(uint32_t, int) override {}
79 void println(int, int) override {}
80};
81
82class StubCrypto final : public CW_CryptoProvider {
83public:
84 bool sha256(const uint8_t*, size_t, uint8_t*) override { return false; }
85 bool sha512(const uint8_t*, size_t, uint8_t*) override { return false; }
86 uint16_t aesCbcEncrypt(const uint8_t*, uint16_t, uint8_t*,
87 const uint8_t*, uint8_t,
88 uint8_t*, bool) override { return 0U; }
89 uint16_t aesCbcDecrypt(uint8_t*, uint16_t, uint8_t*,
90 const uint8_t*, uint8_t,
91 uint8_t*, bool) override { return 0U; }
92 bool ecdh(const uint8_t*, const uint8_t*, uint8_t*,
93 CW_Curve) override { return false; }
94 bool makeKey(uint8_t*, uint8_t*,
95 CW_Curve) override { return false; }
96 bool random(uint8_t*, unsigned) override { return false; }
97 bool ecdsaVerify(const uint8_t*, const uint8_t*, size_t,
98 const uint8_t*, CW_Curve) override { return false; }
99};
100
101class StubPlatform final : public CW_Platform {
102public:
103 void sleep_ms(uint32_t) override {}
104};
105
106/* ── CW_Utils::fill_secure_random stub ─────────────────────────────────
107 * The real implementation is ESP32-specific (esp32_random.cpp).
108 * The DER parsers never call this; the stub exists only for the linker. */
109bool CW_Utils::fill_secure_random(uint8_t* dest, size_t len) {
110 if ((dest != NULL) && (len > 0U)) {
111 memset(dest, 0xA5U, len);
112 }
113 return true;
114}
115
116/* ── Pull in the production code under test ─────────────────────────── */
117#include "../CW_Utils.cpp"
119
120/* ── DerFuzzTarget: bridge from friend to private parseDerSigToRaw ──── */
122 static bool parseDerSigToRaw(const uint8_t* der,
123 uint8_t derLen,
124 uint8_t* raw64) {
125 return CW_SecureChannel::parseDerSigToRaw(der, derLen, raw64);
126 }
127};
128
129/* ── libFuzzer entry point ─────────────────────────────────────────── */
130extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
131 if (size < 1U) {
132 return 0;
133 }
134
135 const uint8_t selector = data[0];
136 const uint8_t* payload = data + 1U;
137 const size_t payloadSize = size - 1U;
138
139 /* ── Target A: parseDerSigToRaw ─────────────────────────────────── */
140 if ((selector == 0x00U) || (selector > 0x01U)) {
141 uint8_t raw64[64U] = { 0U };
142 uint8_t derLen = (payloadSize <= 255U)
143 ? static_cast<uint8_t>(payloadSize)
144 : 255U;
145 (void)DerFuzzTarget::parseDerSigToRaw(payload, derLen, raw64);
146 }
147
148 /* ── Target B: derWalkMfCert ────────────────────────────────────── */
149 if ((selector == 0x01U) || (selector > 0x01U)) {
150 uint16_t tbsMsgStart = 0U;
151 uint16_t tbsMsgLen = 0U;
152 const uint8_t* pubKey65Ptr = NULL;
153 const uint8_t* sigPtr = NULL;
154 uint8_t sigLen = 0U;
155 uint16_t bufLen = (payloadSize <= 0xFFFFU)
156 ? static_cast<uint16_t>(payloadSize)
157 : 0xFFFFU;
158 (void)derWalkMfCert(payload, bufLen,
159 tbsMsgStart, tbsMsgLen,
160 pubKey65Ptr, sigPtr, sigLen);
161 }
162
163 return 0;
164}
Abstract cryptographic primitives interface.
Abstract logging interface.
Abstract NFC transport interface.
Abstract platform interface for timing primitives.
Implementation of the Cryptnox secure channel protocol.
static bool derWalkMfCert(const uint8_t *buf, uint16_t bufLen, uint16_t &tbsMsgStart, uint16_t &tbsMsgLen, const uint8_t *&pubKey65Ptr, const uint8_t *&sigPtr, uint8_t &sigLen)
Cryptnox secure channel protocol over NFC.
Implementation of the platform-independent utility helpers.
Abstract interface for cryptographic operations used by CW_SecureChannel.
Abstract interface for serial/debug output.
Definition CW_Logger.h:48
Abstract interface for NFC transport operations.
Abstract interface for platform-specific operations used by the SDK.
Definition CW_Platform.h:39
static bool parseDerSigToRaw(const uint8_t *der, uint8_t derLen, uint8_t *raw64)
static bool fill_secure_random(uint8_t *dest, size_t len)
Fill len bytes at dest with cryptographically random data.
Definition fuzz_der.cpp:109
bool sha512(const uint8_t *, size_t, uint8_t *) override
Compute SHA-512 over a contiguous data buffer.
Definition fuzz_der.cpp:85
bool random(uint8_t *, unsigned) override
Fill a buffer with cryptographically random bytes.
Definition fuzz_der.cpp:96
bool makeKey(uint8_t *, uint8_t *, CW_Curve) override
Generate a new EC key pair.
Definition fuzz_der.cpp:94
uint16_t aesCbcEncrypt(const uint8_t *, uint16_t, uint8_t *, const uint8_t *, uint8_t, uint8_t *, bool) override
AES-CBC encrypt.
Definition fuzz_der.cpp:86
bool ecdsaVerify(const uint8_t *, const uint8_t *, size_t, const uint8_t *, CW_Curve) override
Verify an ECDSA signature (raw r||s, 64 bytes) against a message hash.
Definition fuzz_der.cpp:97
uint16_t aesCbcDecrypt(uint8_t *, uint16_t, uint8_t *, const uint8_t *, uint8_t, uint8_t *, bool) override
AES-CBC decrypt.
Definition fuzz_der.cpp:89
bool ecdh(const uint8_t *, const uint8_t *, uint8_t *, CW_Curve) override
ECDH shared secret computation.
Definition fuzz_der.cpp:92
bool sha256(const uint8_t *, size_t, uint8_t *) override
Compute SHA-256 over a contiguous data buffer.
Definition fuzz_der.cpp:84
void print(uint32_t, int) override
Definition fuzz_der.cpp:70
void print(int, int) override
Definition fuzz_der.cpp:71
void println(const char *) override
Definition fuzz_der.cpp:74
void print(uint8_t, int) override
Definition fuzz_der.cpp:68
void println(uint8_t, int) override
Definition fuzz_der.cpp:76
void println(char) override
Definition fuzz_der.cpp:75
void print(const __FlashStringHelper *) override
Definition fuzz_der.cpp:65
void println() override
Definition fuzz_der.cpp:72
void println(uint16_t, int) override
Definition fuzz_der.cpp:77
bool begin(unsigned long) override
Initialize the logging interface.
Definition fuzz_der.cpp:64
void print(char) override
Definition fuzz_der.cpp:67
void print(const char *) override
Definition fuzz_der.cpp:66
void println(const __FlashStringHelper *) override
Definition fuzz_der.cpp:73
void print(uint16_t, int) override
Definition fuzz_der.cpp:69
void println(uint32_t, int) override
Definition fuzz_der.cpp:78
void println(int, int) override
Definition fuzz_der.cpp:79
bool sendAPDU(const uint8_t *, uint8_t, uint8_t *, uint8_t &) override
Send an APDU command to the card and receive the response.
Definition fuzz_der.cpp:56
bool inListPassiveTarget() override
Detect the presence of a passive ISO-DEP NFC target.
Definition fuzz_der.cpp:55
bool begin() override
Initialize the NFC transport hardware.
Definition fuzz_der.cpp:54
bool printFirmwareVersion() override
Print NFC module firmware version information to the logger.
Definition fuzz_der.cpp:59
void resetReader() override
Reset the NFC reader/field for the next card detection cycle.
Definition fuzz_der.cpp:58
void sleep_ms(uint32_t) override
Block for at least ms milliseconds.
Definition fuzz_der.cpp:103
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition fuzz_der.cpp:130
CW_Curve
Portable curve identifier used throughout the SDK.
Definition CW_Defs.h:151
static bool parseDerSigToRaw(const uint8_t *der, uint8_t derLen, uint8_t *raw64)
Definition fuzz_der.cpp:122