Skip to content

Commit 94c1812

Browse files
committed
WIP
1 parent a559b75 commit 94c1812

File tree

7 files changed

+407
-137
lines changed

7 files changed

+407
-137
lines changed

.github/workflows/test-library.yml

Lines changed: 98 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
fail-fast: false
2121

2222
# Limit concurrent jobs for scheduling problem on GitHub's hosted runner pool.
23-
max-parallel: 12
23+
max-parallel: 10
2424

2525
matrix:
2626
math:
@@ -31,7 +31,7 @@ jobs:
3131
- "SPMATH=0 SPMATHALL=0 WOLFBOOT_SMALL_STACK=0"
3232
- "SPMATH=0 SPMATHALL=0 WOLFBOOT_SMALL_STACK=1"
3333
asym: [ed25519, ecc256, ecc384, ecc521, rsa2048, rsa3072, rsa4096, ed448]
34-
hash: [sha256, sha384, sha3]
34+
hash: [sha256, sha384, sha3] # --sha256 for commandline, SHA256 for make
3535

3636
# See https://github.com/wolfSSL/wolfBoot/issues/614 regarding exclusions:
3737
exclude:
@@ -41,41 +41,104 @@ jobs:
4141
steps:
4242
- uses: actions/checkout@v4
4343
with:
44+
clean: true
4445
submodules: true
4546

46-
- name: make clean
47+
- name: dist clean
4748
run: |
48-
make keysclean && make -C tools/keytools clean && rm -f include/target.h
49+
# Ensure parallel build did not leave behind any debris
50+
make distclean
4951
5052
- name: Build test-lib
5153
env:
5254
shell: bash
53-
ASYM: ${{ matrix.asym }}
55+
ASYM: ${{ matrix.asym }} # MAKE_SIGN in upper case
5456
HASH: ${{ matrix.hash }}
5557
MATH: ${{ matrix.math }}
5658
run: |
59+
# Test various library parameters
60+
61+
export MAKE_SIGN="${ASYM^^}"
62+
export MAKE_HASH="${HASH^^}"
63+
export MAKE_MATH='${{ matrix.math }}' # e.g., "SPMATH=1 WOLFBOOT_SMALL_STACK=1"
64+
export PRIVATE_KEY="wolfboot_signing_private_key.der"
65+
66+
echo "This MAKE_SIGN=$MAKE_SIGN"
67+
echo "This MAKE_HASH=$MAKE_HASH"
68+
echo "This MAKE_MATH=$MAKE_MATH"
69+
5770
# Sample build
5871
build_once() {
5972
# Convert asym and hash to upper case, optionally add additional param
60-
make -j test-lib SIGN=${ASYM^^} HASH=${HASH^^} ${MATH} "$@"
73+
echo "Build test-lib..."
74+
echo "make -j1 test-lib SIGN=${MAKE_SIGN} HASH=${MAKE_HASH} ${MATH} \"$@\""
75+
make -j1 test-lib SIGN=${MAKE_SIGN} HASH=${MAKE_HASH} ${MATH} "$@"
6176
}
6277
6378
set -euo pipefail
6479
6580
# Get the reference config
6681
cp config/examples/library.config .config
6782
83+
# peek
84+
echo "Existing files?"
85+
if [ -f "src/keystore.c" ]; then
86+
echo "WARNING: Found unexpected src/keystore.c"
87+
fi
88+
if [ -f "include/target.h" ]; then
89+
echo "WARNING: Found unexpected include/target.h"
90+
fi
91+
if [ -f "keystore.der" ]; then
92+
echo "WARNING: Found unexpected keystore.der"
93+
fi
94+
if [ -f "wolfboot_signing_private_key.der" ]; then
95+
echo "WARNING: Found unexpected wolfboot_signing_private_key.der"
96+
fi
97+
if [ -f "./tools/keytools/keystore.der" ]; then
98+
echo "WARNING: Found unexpected ./tools/keytools/keystore.der"
99+
fi
100+
if [ -f "./tools/keytools/wolfboot_signing_private_key.der" ]; then
101+
echo "WARNING: Found unexpected ./tools/keytools/wolfboot_signing_private_key.der"
102+
fi
103+
68104
# Keytools
69-
make keytools
70-
./tools/keytools/keygen --${ASYM} -g wolfboot_signing_private_key.der
105+
echo ""
106+
echo "make -j1 keytools SIGN=\"${MAKE_SIGN}\" HASH=\"${MAKE_HASH}\" $MATH"
107+
make -j1 keytools SIGN="${MAKE_SIGN}" HASH="${MAKE_HASH}" $MATH
108+
109+
# Generate keys
110+
echo ""
111+
echo "./tools/keytools/keygen --${ASYM} -g wolfboot_signing_private_key.der"
112+
./tools/keytools/keygen --${ASYM} -g wolfboot_signing_private_key.der
113+
114+
# Force fresh files
115+
# peek
116+
echo "Existing files?"
117+
if [ -f "src/keystore.c" ]; then
118+
echo "Found unexpected src/keystore.c"
119+
fi
120+
if [ -f "include/target.h" ]; then
121+
echo "Found unexpected include/target.h"
122+
fi
123+
if [ -f "keystore.der" ]; then
124+
echo "Found unexpected keystore.der"
125+
fi
126+
if [ -f "wolfboot_signing_private_key.der" ]; then
127+
echo "Found unexpected wolfboot_signing_private_key.der"
128+
fi
71129
72130
# Sign
131+
echo ""
73132
echo "Test" > test.bin
74-
./tools/keytools/sign --${ASYM} --${HASH} test.bin wolfboot_signing_private_key.der 1
133+
echo "Sign test.bin"
134+
echo "./tools/keytools/sign --${ASYM} --${HASH} test.bin wolfboot_signing_private_key.der 1"
135+
./tools/keytools/sign --${ASYM} --${HASH} test.bin wolfboot_signing_private_key.der 1
75136
76137
# First attempt
77138
if build_once >build.out 2>build.err; then
78139
echo "Success on first attempt, WOLFBOOT_HUGE_STACK not applied."
140+
cat build.out
141+
cat build.err
79142
exit 0
80143
fi
81144
@@ -90,12 +153,16 @@ jobs:
90153
build_once WOLFBOOT_HUGE_STACK=1
91154
else
92155
echo "Build failed for another reason:"
156+
cat build.out
93157
cat build.err
94158
exit 1
95159
fi
96160
97161
- name: Run test-lib
98162
run: |
163+
# Check test_v1_signed.bin
164+
165+
echo "./test-lib test_v1_signed.bin"
99166
./test-lib test_v1_signed.bin
100167
./test-lib test_v1_signed.bin 2>&1 | grep "Firmware Valid"
101168
@@ -104,5 +171,25 @@ jobs:
104171
# Corrupt signed binary
105172
truncate -s -1 test_v1_signed.bin
106173
echo "A" >> test_v1_signed.bin
107-
./test-lib test_v1_signed.bin
108-
./test-lib test_v1_signed.bin 2>&1 | grep "Failure"
174+
175+
# Run once, capture output and status
176+
set +e
177+
output=$(./test-lib test_v1_signed.bin 2>&1)
178+
status=$?
179+
set -e
180+
181+
echo "$output"
182+
183+
# Must have failed (non-zero exit)
184+
if [ $status -eq 0 ]; then
185+
echo "Expected failure, but exit code was 0"
186+
exit 1
187+
fi
188+
189+
# Must include the expected Failure message
190+
echo "$output" | grep -F "Failure" >/dev/null || {
191+
echo "Expected 'Failure' not found in output"
192+
exit 1
193+
}
194+
195+
echo "Got expected non-zero exit and 'Failure' message."

hal/library.c

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,17 @@ int wolfBoot_start(void)
130130
os_image.hdr = (uint8_t*)gImage;
131131

132132
if ((ret = wolfBoot_open_image_address(&os_image, (uint8_t*)gImage)) < 0) {
133+
wolfBoot_printf("Failed to open image address.\n");
133134
goto exit;
134135
}
135136

136137
if ((ret = wolfBoot_verify_integrity(&os_image)) < 0) {
138+
wolfBoot_printf("Failed to verify integrity.\n");
137139
goto exit;
138140
}
139141

140142
if ((ret = wolfBoot_verify_authenticity(&os_image)) < 0) {
143+
wolfBoot_printf("Failed to verify authenticity.\n");
141144
goto exit;
142145
}
143146

@@ -148,11 +151,13 @@ int wolfBoot_start(void)
148151
exit:
149152
if (ret < 0) {
150153
wolfBoot_printf("Failure %d: Hdr %d, Hash %d, Sig %d\n", ret,
151-
(int)os_image.hdr_ok, (int)os_image.sha_ok,
152-
(int)os_image.signature_ok);
154+
os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
155+
return -1;
156+
}
157+
else {
158+
return 0;
153159
}
154160

155-
return 0;
156161
}
157162

158163

@@ -161,39 +166,62 @@ int main(int argc, const char* argv[])
161166
int ret = 0;
162167

163168
#ifdef NO_FILESYSTEM
169+
wolfBoot_printf("NO_FILESYSTEM is defined, looking at test_img");
164170
gImage = (uintptr_t)test_img;
165171
#else
166-
if (argc > 1) {
167-
size_t sz = 0, bread;
172+
if (argc == 2) {
173+
size_t sz = 0, bread = 0;
168174
FILE* img = fopen(argv[1], "rb");
169175
if (img == NULL) {
170-
wolfBoot_printf("failed to open %s!\n", argv[1]);
176+
wolfBoot_printf("Failed to open file: %s!\n\n", argv[1]);
177+
wolfBoot_printf("Usage: %s image_file.bin\n", argv[0]);
171178
return -3;
172179
}
173-
fseek(img, 0, SEEK_END);
174-
sz = ftell(img);
175-
fseek(img, 0, SEEK_SET);
180+
else {
181+
wolfBoot_printf("Looking at image file: %s\n", argv[1]);
182+
fseek(img, 0, SEEK_END);
183+
sz = ftell(img);
184+
fseek(img, 0, SEEK_SET);
185+
186+
gImage = (uintptr_t)malloc(sz);
187+
}
176188

177-
gImage = (uintptr_t)malloc(sz);
178189
if (((void*)gImage) == NULL) {
179-
wolfBoot_printf("failed to malloc %zu bytes for image\n", sz);
190+
wolfBoot_printf("Failed to malloc %zu bytes for image.\n", sz);
180191
ret = -1;
181192
}
193+
else {
194+
/* check the image */
195+
bread = fread((void*)gImage, 1, sz, img);
196+
}
182197

183-
bread = fread((void*)gImage, 1, sz, img);
184-
if (bread != sz) {
198+
if (bread == sz) {
199+
wolfBoot_printf("Confirmed expected size: %zu bytes.\n", bread);
200+
}
201+
else {
185202
ret = -2;
186-
wolfBoot_printf("read %zu of %zu bytes from %s\n", bread, sz, argv[1]);
203+
wolfBoot_printf("Read %zu of %zu bytes from %s\n", bread, sz, argv[1]);
187204
}
188205
fclose(img);
189-
} else {
206+
}
207+
else {
190208
wolfBoot_printf("usage: %s image_file.bin\n", argv[0]);
191209
ret = 255;
192210
}
193211
#endif
194212
if (ret == 0) {
213+
wolfBoot_printf("Checking image... ");
195214
ret = wolfBoot_start();
196215
}
216+
if (ret == 0) {
217+
wolfBoot_printf("Success!\n");
218+
}
219+
else {
220+
if (ret != 255) {
221+
/* Only show error if we actually processed file, not missing params */
222+
wolfBoot_printf("Failed to verify with wolfBoot_start\n");
223+
}
224+
}
197225

198226
#ifndef NO_FILESYSTEM
199227
if ((void*)gImage != NULL)

include/printf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@
6666
# elif defined(WOLFBOOT_LOG_PRINTF)
6767
/* allow output to stdout */
6868
# define wolfBoot_printf(_f_, ...) printf(_f_, ##__VA_ARGS__)
69+
# elif defined(_MSC_VER)
70+
# include <stdio.h>
71+
# define wolfBoot_printf(...) do { fprintf(stderr, __VA_ARGS__); } while (0)
6972
# else
7073
/* use stderr by default */
7174
# define wolfBoot_printf(_f_, ...) fprintf(stderr, _f_, ##__VA_ARGS__)

src/image.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ static int header_sha256(wc_Sha256 *sha256_ctx, struct wolfBoot_image *img)
946946
while (p < end_sha) {
947947
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
948948
if (end_sha - p < blksz)
949-
blksz = end_sha - p;
949+
blksz = (int)(end_sha - p);
950950
wc_Sha256Update(sha256_ctx, p, blksz);
951951
p += blksz;
952952
}
@@ -993,20 +993,28 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
993993
* @param key_slot The key slot ID to calculate the hash for.
994994
* @param hash A pointer to store the resulting SHA256 hash.
995995
*/
996-
static void key_sha256(uint8_t key_slot, uint8_t *hash)
996+
static int key_sha256(uint8_t key_slot, uint8_t *hash)
997997
{
998998
uint8_t *pubkey = keystore_get_buffer(key_slot);
999999
int pubkey_sz = keystore_get_size(key_slot);
10001000
wc_Sha256 sha256_ctx;
1001+
int ret = 0;
1002+
1003+
if (!pubkey || (pubkey_sz < 0)) {
1004+
return -1;
1005+
}
10011006

10021007
memset(hash, 0, SHA256_DIGEST_SIZE);
1003-
if (!pubkey || (pubkey_sz < 0))
1004-
return;
10051008

1006-
wc_InitSha256(&sha256_ctx);
1007-
wc_Sha256Update(&sha256_ctx, pubkey, (word32)pubkey_sz);
1008-
wc_Sha256Final(&sha256_ctx, hash);
1009+
ret = wc_InitSha256(&sha256_ctx);
1010+
if (ret == 0) {
1011+
ret = wc_Sha256Update(&sha256_ctx, pubkey, (word32)pubkey_sz);
1012+
}
1013+
if (ret == 0) {
1014+
ret = wc_Sha256Final(&sha256_ctx, hash);
1015+
}
10091016
wc_Sha256Free(&sha256_ctx);
1017+
return ret;
10101018
}
10111019
#endif /* WOLFBOOT_NO_SIGN */
10121020
#endif /* SHA2-256 */
@@ -2205,18 +2213,34 @@ uint8_t* wolfBoot_peek_image(struct wolfBoot_image *img, uint32_t offset,
22052213
*
22062214
* @param hint The SHA hash of the public key to search for.
22072215
* @return The key slot ID if found, -1 if the key was not found.
2216+
* Other negative values if the key_hash function failed.
22082217
*/
2218+
22092219
int keyslot_id_by_sha(const uint8_t *hint)
22102220
{
22112221
int id;
2222+
int ret = -1;
2223+
int ct = 0;
2224+
if (hint == NULL) {
2225+
return -1;
2226+
}
22122227

22132228
for (id = 0; id < keystore_num_pubkeys(); id++) {
2214-
key_hash(id, digest);
2215-
if (memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0) {
2229+
ct++;
2230+
ret = key_hash(id, digest);
2231+
if ((ret == 0) && memcmp(digest, hint, WOLFBOOT_SHA_DIGEST_SIZE) == 0) {
2232+
wolfBoot_printf("Found matching digest in slot %d\n", id);
22162233
return id;
22172234
}
22182235
}
2219-
return -1;
2236+
2237+
if (ret == 0) {
2238+
/* Calls to key_hash were successful, but we did not find one. Fail: */
2239+
wolfBoot_printf("No matching key hash found. Looked at %d slot(s)", ct);
2240+
ret = -1;
2241+
}
2242+
/* Reminder: zero based slot array. */
2243+
return ret;
22202244
}
22212245
#endif /* !WOLFBOOT_NO_SIGN && !WOLFBOOT_RENESAS_SCEPROTECT */
22222246

0 commit comments

Comments
 (0)