Skip to content

Commit 5f13d7d

Browse files
authored
Merge pull request #703 from danielinux/enforce-signature-size
Enforce checking signature size
2 parents 2d74aae + d01077d commit 5f13d7d

File tree

3 files changed

+184
-20
lines changed

3 files changed

+184
-20
lines changed

src/image.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2222,6 +2222,41 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
22222222
}
22232223
#endif
22242224

2225+
if (stored_signature_size == 0 || stored_signature == NULL) {
2226+
return -1;
2227+
}
2228+
#if defined(WOLFBOOT_SIGN_ED25519)
2229+
if (stored_signature_size != ED25519_IMAGE_SIGNATURE_SIZE)
2230+
return -1;
2231+
#elif defined(WOLFBOOT_SIGN_ED448)
2232+
if (stored_signature_size != ED448_IMAGE_SIGNATURE_SIZE)
2233+
return -1;
2234+
#elif defined (WOLFBOOT_SIGN_RSA2048) || \
2235+
defined (WOLFBOOT_SIGN_RSA3072) || \
2236+
defined (WOLFBOOT_SIGN_RSA4096) || \
2237+
defined (WOLFBOOT_SIGN_RSA2048ENC) || \
2238+
defined (WOLFBOOT_SIGN_RSA3072ENC) || \
2239+
defined (WOLFBOOT_SIGN_RSA4096ENC)
2240+
if (stored_signature_size != RSA_IMAGE_SIGNATURE_SIZE)
2241+
return -1;
2242+
#elif defined (WOLFBOOT_SIGN_ECC256) || \
2243+
defined (WOLFBOOT_SIGN_ECC384) || \
2244+
defined (WOLFBOOT_SIGN_ECC521)
2245+
if (stored_signature_size != ECC_IMAGE_SIGNATURE_SIZE)
2246+
return -1;
2247+
#elif defined(WOLFBOOT_SIGN_LMS)
2248+
if (stored_signature_size != LMS_IMAGE_SIGNATURE_SIZE)
2249+
return -1;
2250+
#elif defined(WOLFBOOT_SIGN_XMSS)
2251+
if (stored_signature_size != XMSS_IMAGE_SIGNATURE_SIZE)
2252+
return -1;
2253+
#elif defined(WOLFBOOT_SIGN_ML_DSA)
2254+
if (stored_signature_size != ML_DSA_IMAGE_SIGNATURE_SIZE)
2255+
return -1;
2256+
#else
2257+
return -1;
2258+
#endif
2259+
22252260
/* wolfBoot_verify_signature_ecc() does not return the result directly.
22262261
* A call to wolfBoot_image_confirm_signature_ok() is required in order to
22272262
* confirm that the signature verification is OK.
@@ -2231,7 +2266,6 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
22312266
*
22322267
*/
22332268
wolfBoot_verify_signature_primary(key_slot, img, stored_signature);
2234-
(void)stored_signature_size;
22352269

22362270
#ifdef WOLFBOOT_ARMORED
22372271
#define SIG_OK(imgp) (((imgp)->signature_ok == 1) && \

tools/unit-tests/unit-image.c

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,15 @@
4242
#define ECC_TIMING_RESISTANT
4343

4444
#define ENCRYPT_KEY "123456789abcdef0123456789abcdef0123456789abcdef"
45-
#define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC256
45+
#if !defined(WOLFBOOT_SIGN_ED25519) && !defined(WOLFBOOT_SIGN_ED448) && \
46+
!defined(WOLFBOOT_SIGN_RSA2048) && !defined(WOLFBOOT_SIGN_RSA3072) && \
47+
!defined(WOLFBOOT_SIGN_RSA4096) && !defined(WOLFBOOT_SIGN_RSA2048ENC) && \
48+
!defined(WOLFBOOT_SIGN_RSA3072ENC) && !defined(WOLFBOOT_SIGN_RSA4096ENC) && \
49+
!defined(WOLFBOOT_SIGN_ECC256) && !defined(WOLFBOOT_SIGN_ECC384) && \
50+
!defined(WOLFBOOT_SIGN_ECC521) && !defined(WOLFBOOT_SIGN_LMS) && \
51+
!defined(WOLFBOOT_SIGN_XMSS) && !defined(WOLFBOOT_SIGN_ML_DSA)
4652
#define WOLFBOOT_SIGN_ECC256
53+
#endif
4754

4855
#include <stdio.h>
4956
#include <check.h>
@@ -69,11 +76,13 @@ static int find_header_fail = 0;
6976
static int find_header_called = 0;
7077
static int find_header_mocked = 1;
7178

79+
#if defined(WOLFBOOT_SIGN_ECC256)
7280
static const unsigned char pubkey_digest[SHA256_DIGEST_SIZE] = {
7381
0x17, 0x20, 0xa5, 0x9b, 0xe0, 0x9b, 0x80, 0x0c, 0xaa, 0xc4, 0xf5, 0x3f,
7482
0xae, 0xe5, 0x72, 0x4f, 0xf2, 0x1f, 0x33, 0x53, 0xd1, 0xd4, 0xcd, 0x8b,
7583
0x5c, 0xc3, 0x4e, 0xda, 0xea, 0xc8, 0x4a, 0x68
7684
};
85+
#endif
7786

7887

7988
uint32_t wolfBoot_get_blob_version(uint8_t *blob)
@@ -161,6 +170,48 @@ static const unsigned char test_img_v200000000_wrong_pubkey_bin[] = {
161170
0xff, 0xff, 0xff, 0xff, 0x54, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6d, 0x61,
162171
0x67, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x0a
163172
};
173+
174+
static uint16_t _find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
175+
176+
static void patch_pubkey_hint(uint8_t *img, uint32_t img_len)
177+
{
178+
uint8_t *ptr = NULL;
179+
uint16_t len;
180+
uint8_t hash[SHA256_DIGEST_SIZE];
181+
182+
(void)img_len;
183+
len = _find_header(img + IMAGE_HEADER_OFFSET, HDR_PUBKEY, &ptr);
184+
ck_assert_int_eq(len, WOLFBOOT_SHA_DIGEST_SIZE);
185+
key_sha256(0, hash);
186+
memcpy(ptr, hash, WOLFBOOT_SHA_DIGEST_SIZE);
187+
}
188+
189+
static void patch_signature_len(uint8_t *img, uint32_t img_len, uint16_t new_len)
190+
{
191+
uint8_t *ptr = NULL;
192+
uint16_t len;
193+
194+
(void)img_len;
195+
len = _find_header(img + IMAGE_HEADER_OFFSET, HDR_SIGNATURE, &ptr);
196+
ck_assert_int_ne(len, 0);
197+
ptr[-2] = (uint8_t)(new_len & 0xFF);
198+
ptr[-1] = (uint8_t)(new_len >> 8);
199+
}
200+
201+
static void patch_image_type_auth(uint8_t *img, uint32_t img_len)
202+
{
203+
uint8_t *ptr = NULL;
204+
uint16_t len;
205+
uint16_t type;
206+
207+
(void)img_len;
208+
len = _find_header(img + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE, &ptr);
209+
ck_assert_int_eq(len, sizeof(uint16_t));
210+
type = (uint16_t)(ptr[0] | (ptr[1] << 8));
211+
type = (uint16_t)((type & ~HDR_IMG_TYPE_AUTH_MASK) | HDR_IMG_TYPE_AUTH);
212+
ptr[0] = (uint8_t)(type & 0xFF);
213+
ptr[1] = (uint8_t)(type >> 8);
214+
}
164215
static const unsigned int test_img_len = 275;
165216

166217

@@ -392,7 +443,12 @@ START_TEST(test_sha_ops)
392443

393444
/* key_sha256 */
394445
key_sha256(0, hash);
446+
#if defined(WOLFBOOT_SIGN_ECC256)
395447
ck_assert_mem_eq(hash, pubkey_digest, SHA256_DIGEST_SIZE);
448+
#else
449+
/* For non-ECC256 configurations we do not have a fixed expected digest. */
450+
(void)hash;
451+
#endif
396452
}
397453
END_TEST
398454

@@ -495,6 +551,29 @@ START_TEST(test_verify_authenticity)
495551
}
496552
END_TEST
497553

554+
START_TEST(test_verify_authenticity_bad_siglen)
555+
{
556+
struct wolfBoot_image test_img;
557+
uint8_t buf[sizeof(test_img_v200000000_signed_bin)];
558+
int ret;
559+
560+
memcpy(buf, test_img_v200000000_signed_bin, sizeof(buf));
561+
patch_image_type_auth(buf, sizeof(buf));
562+
patch_pubkey_hint(buf, sizeof(buf));
563+
patch_signature_len(buf, sizeof(buf), 1);
564+
565+
find_header_mocked = 0;
566+
find_header_fail = 0;
567+
hdr_cpy_done = 0;
568+
ext_flash_write(0, buf, sizeof(buf));
569+
570+
memset(&test_img, 0, sizeof(struct wolfBoot_image));
571+
test_img.part = PART_UPDATE;
572+
ret = wolfBoot_verify_authenticity(&test_img);
573+
ck_assert_int_eq(ret, -1);
574+
}
575+
END_TEST
576+
498577
START_TEST(test_verify_integrity)
499578
{
500579
struct wolfBoot_image test_img;
@@ -599,6 +678,7 @@ Suite *wolfboot_suite(void)
599678
TCase* tcase_verify_authenticity = tcase_create("verify_authenticity");
600679
tcase_set_timeout(tcase_verify_authenticity, 20);
601680
tcase_add_test(tcase_verify_authenticity, test_verify_authenticity);
681+
tcase_add_test(tcase_verify_authenticity, test_verify_authenticity_bad_siglen);
602682
suite_add_tcase(s, tcase_verify_authenticity);
603683

604684
TCase* tcase_verify_integrity = tcase_create("verify_integrity");

tools/unit-tests/unit-keystore.c

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,36 +28,87 @@
2828
#define NUM_PUBKEYS 0
2929
#else
3030

31-
#if !defined(KEYSTORE_ANY) && (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_ECC256)
32-
#error Key algorithm mismatch. Remove old keys via 'make keysclean'
33-
#else
34-
3531
#if defined(__APPLE__) && defined(__MACH__)
3632
#define KEYSTORE_SECTION __attribute__((section ("__KEYSTORE,__keystore")))
3733
#else
3834
#define KEYSTORE_SECTION __attribute__((section (".keystore")))
3935
#endif
4036

37+
#if defined(WOLFBOOT_SIGN_ED25519)
38+
#define UNIT_KEY_TYPE AUTH_KEY_ED25519
39+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ED25519
40+
#define UNIT_PUBKEY_INIT { 0x00 }
41+
#elif defined(WOLFBOOT_SIGN_ED448)
42+
#define UNIT_KEY_TYPE AUTH_KEY_ED448
43+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ED448
44+
#define UNIT_PUBKEY_INIT { 0x00 }
45+
#elif defined(WOLFBOOT_SIGN_RSA2048) || defined(WOLFBOOT_SIGN_RSA2048ENC)
46+
#define UNIT_KEY_TYPE AUTH_KEY_RSA2048
47+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_RSA2048
48+
#define UNIT_PUBKEY_INIT { 0x00 }
49+
#elif defined(WOLFBOOT_SIGN_RSA3072) || defined(WOLFBOOT_SIGN_RSA3072ENC)
50+
#define UNIT_KEY_TYPE AUTH_KEY_RSA3072
51+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_RSA3072
52+
#define UNIT_PUBKEY_INIT { 0x00 }
53+
#elif defined(WOLFBOOT_SIGN_RSA4096) || defined(WOLFBOOT_SIGN_RSA4096ENC)
54+
#define UNIT_KEY_TYPE AUTH_KEY_RSA4096
55+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_RSA4096
56+
#define UNIT_PUBKEY_INIT { 0x00 }
57+
#elif defined(WOLFBOOT_SIGN_ECC384)
58+
#define UNIT_KEY_TYPE AUTH_KEY_ECC384
59+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC384
60+
#define UNIT_PUBKEY_INIT { 0x00 }
61+
#elif defined(WOLFBOOT_SIGN_ECC521)
62+
#define UNIT_KEY_TYPE AUTH_KEY_ECC521
63+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC521
64+
#define UNIT_PUBKEY_INIT { 0x00 }
65+
#elif defined(WOLFBOOT_SIGN_LMS)
66+
#define UNIT_KEY_TYPE AUTH_KEY_LMS
67+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_LMS
68+
#define UNIT_PUBKEY_INIT { 0x00 }
69+
#elif defined(WOLFBOOT_SIGN_XMSS)
70+
#define UNIT_KEY_TYPE AUTH_KEY_XMSS
71+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_XMSS
72+
#define UNIT_PUBKEY_INIT { 0x00 }
73+
#elif defined(WOLFBOOT_SIGN_ML_DSA)
74+
#define UNIT_KEY_TYPE AUTH_KEY_ML_DSA
75+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ML_DSA
76+
#define UNIT_PUBKEY_INIT { 0x00 }
77+
#else
78+
#define UNIT_KEY_TYPE AUTH_KEY_ECC256
79+
#define UNIT_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_ECC256
80+
#define UNIT_PUBKEY_INIT { \
81+
0xc5, 0x7d, 0xbf, 0xfb, 0x23, 0x79, 0xba, 0xb6, \
82+
0x31, 0x8f, 0x7b, 0x8d, 0xfe, 0xc9, 0x5d, 0x46, \
83+
0xf5, 0x95, 0xb4, 0xa8, 0xbd, 0x45, 0xb7, 0x46, \
84+
0xf3, 0x6c, 0x1b, 0x86, 0x28, 0x7b, 0x23, 0xd1, \
85+
0x83, 0xf3, 0x27, 0x5c, 0x08, 0x1f, 0x9d, 0x9e, \
86+
0x6c, 0xca, 0xee, 0xb3, 0x0d, 0x5c, 0x01, 0xb2, \
87+
0xc5, 0x98, 0xf3, 0x85, 0x6c, 0xdd, 0x42, 0x54, \
88+
0xef, 0x44, 0x94, 0x59, 0xf3, 0x08, 0x3d, 0xcd \
89+
}
90+
#endif
91+
92+
#if defined(KEYSTORE_ANY)
93+
#if UNIT_PUBKEY_SIZE > KEYSTORE_PUBKEY_SIZE
94+
#error Key algorithm mismatch. Remove old keys via 'make keysclean'
95+
#endif
96+
#else
97+
#if KEYSTORE_PUBKEY_SIZE != UNIT_PUBKEY_SIZE
98+
#error Key algorithm mismatch. Remove old keys via 'make keysclean'
99+
#endif
100+
#endif
101+
41102
#define NUM_PUBKEYS 1
42103
const KEYSTORE_SECTION struct keystore_slot PubKeys[NUM_PUBKEYS] = {
43104

44105
/* Key associated to file 'wolfboot_signing_private_key.der' */
45106
{
46107
.slot_id = 0,
47-
.key_type = AUTH_KEY_ECC256,
108+
.key_type = UNIT_KEY_TYPE,
48109
.part_id_mask = 0xFFFFFFFF,
49-
.pubkey_size = KEYSTORE_PUBKEY_SIZE_ECC256,
50-
.pubkey = {
51-
52-
0xc5, 0x7d, 0xbf, 0xfb, 0x23, 0x79, 0xba, 0xb6,
53-
0x31, 0x8f, 0x7b, 0x8d, 0xfe, 0xc9, 0x5d, 0x46,
54-
0xf5, 0x95, 0xb4, 0xa8, 0xbd, 0x45, 0xb7, 0x46,
55-
0xf3, 0x6c, 0x1b, 0x86, 0x28, 0x7b, 0x23, 0xd1,
56-
0x83, 0xf3, 0x27, 0x5c, 0x08, 0x1f, 0x9d, 0x9e,
57-
0x6c, 0xca, 0xee, 0xb3, 0x0d, 0x5c, 0x01, 0xb2,
58-
0xc5, 0x98, 0xf3, 0x85, 0x6c, 0xdd, 0x42, 0x54,
59-
0xef, 0x44, 0x94, 0x59, 0xf3, 0x08, 0x3d, 0xcd
60-
},
110+
.pubkey_size = UNIT_PUBKEY_SIZE,
111+
.pubkey = UNIT_PUBKEY_INIT,
61112
},
62113

63114

@@ -94,5 +145,4 @@ uint32_t keystore_get_key_type(int id)
94145
return PubKeys[id].key_type;
95146
}
96147

97-
#endif /* Keystore public key size check */
98148
#endif /* WOLFBOOT_NO_SIGN */

0 commit comments

Comments
 (0)