Skip to content

Commit e910380

Browse files
committed
Add support for using an RSA signature that includes ASN.1 encoded header. On by default, can be disabled using NO_RSA_SIG_ENCODING. Added support for signing with encoding using --rsa2048enc or --rsa4096enc.
1 parent 5c2e44a commit e910380

2 files changed

Lines changed: 89 additions & 9 deletions

File tree

src/image.c

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,54 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
115115
#endif /* WOLFBOOT_SIGN_ECC256 */
116116

117117
#if defined(WOLFBOOT_SIGN_RSA2048) || defined (WOLFBOOT_SIGN_RSA4096)
118-
#include <wolfssl/wolfcrypt/asn_public.h>
118+
#include <wolfssl/wolfcrypt/asn.h>
119119
#include <wolfssl/wolfcrypt/rsa.h>
120+
121+
#ifndef NO_RSA_SIG_ENCODING /* option to reduce code size */
122+
static inline int DecodeAsn1Tag(const uint8_t* input, int inputSz, int* inOutIdx,
123+
int* tag_len, uint8_t tag)
124+
{
125+
if (input[*inOutIdx] != tag) {
126+
return -1;
127+
}
128+
(*inOutIdx)++;
129+
*tag_len = input[*inOutIdx];
130+
(*inOutIdx)++;
131+
if (*tag_len + *inOutIdx > inputSz) {
132+
return -1;
133+
}
134+
return 0;
135+
}
136+
static int RsaDecodeSignature(uint8_t** pInput, int inputSz)
137+
{
138+
uint8_t* input = *pInput;
139+
int idx = 0;
140+
int digest_len = 0, algo_len, tot_len;
141+
142+
/* sequence - total size */
143+
if (DecodeAsn1Tag(input, inputSz, &idx, &tot_len,
144+
ASN_SEQUENCE | ASN_CONSTRUCTED) != 0) {
145+
return -1;
146+
}
147+
148+
/* sequence - algoid */
149+
if (DecodeAsn1Tag(input, inputSz, &idx, &algo_len,
150+
ASN_SEQUENCE | ASN_CONSTRUCTED) != 0) {
151+
return -1;
152+
}
153+
idx += algo_len; /* skip algoid */
154+
155+
/* digest */
156+
if (DecodeAsn1Tag(input, inputSz, &idx, &digest_len,
157+
ASN_OCTET_STRING) != 0) {
158+
return -1;
159+
}
160+
/* return digest buffer pointer */
161+
*pInput = &input[idx];
162+
return digest_len;
163+
}
164+
#endif /* !NO_RSA_SIG_ENCODING */
165+
120166
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
121167
{
122168
#ifdef WOLFBOOT_TPM
@@ -142,7 +188,8 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
142188
#else
143189
int ret;
144190
struct RsaKey rsa;
145-
uint8_t digest_out[IMAGE_SIGNATURE_SIZE];
191+
uint8_t* digest_out = NULL;
192+
uint8_t output[IMAGE_SIGNATURE_SIZE];
146193
word32 in_out = 0;
147194

148195
ret = wc_InitRsaKey(&rsa, NULL);
@@ -156,10 +203,18 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
156203
/* Failed to import rsa key */
157204
return -1;
158205
}
159-
ret = wc_RsaSSL_Verify(sig, IMAGE_SIGNATURE_SIZE, digest_out, IMAGE_SIGNATURE_SIZE, &rsa);
160-
if (ret == WOLFBOOT_SHA_DIGEST_SIZE) {
161-
if (memcmp(digest_out, hash, ret) == 0)
162-
return 0;
206+
ret = wc_RsaSSL_Verify(sig, IMAGE_SIGNATURE_SIZE, output,
207+
IMAGE_SIGNATURE_SIZE, &rsa);
208+
digest_out = output;
209+
#ifndef NO_RSA_SIG_ENCODING
210+
if (ret > WOLFBOOT_SHA_DIGEST_SIZE) {
211+
/* larger result indicates it might have an ASN.1 encoded header */
212+
ret = RsaDecodeSignature(&digest_out, ret);
213+
}
214+
#endif
215+
if (ret == WOLFBOOT_SHA_DIGEST_SIZE && digest_out &&
216+
memcmp(digest_out, hash, ret) == 0) {
217+
return 0;
163218
}
164219
return -1;
165220
#endif /* WOLFBOOT_TPM */

tools/keytools/sign.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <sys/types.h>
3838

3939
#include <wolfssl/wolfcrypt/settings.h>
40+
#include <wolfssl/wolfcrypt/asn.h>
4041

4142
#ifdef HAVE_CHACHA
4243
#include <wolfssl/wolfcrypt/chacha.h>
@@ -158,6 +159,7 @@ int main(int argc, char** argv)
158159
uint32_t idx, read_sz, pos;
159160
uint16_t image_type;
160161
uint32_t fw_version32;
162+
uint32_t sign_wenc = 0;
161163
struct stat attrib;
162164
union {
163165
#ifdef HAVE_ED25519
@@ -178,7 +180,7 @@ int main(int argc, char** argv)
178180

179181
/* Check arguments and print usage */
180182
if (argc < 4 || argc > 10) {
181-
printf("Usage: %s [--ed25519 | --ecc256 | --rsa2048 | --rsa4096 ] [--sha256 | --sha3] [--wolfboot-update] [--encrypt enc_key.bin] image key.der fw_version\n", argv[0]);
183+
printf("Usage: %s [--ed25519 | --ecc256 | --rsa2048 | --rsa2048enc | --rsa4096 | --rsa4096enc ] [--sha256 | --sha3] [--wolfboot-update] [--encrypt enc_key.bin] image key.der fw_version\n", argv[0]);
182184
printf(" - or - ");
183185
printf(" %s [--sha256 | --sha3] [--sha-only] [--wolfboot-update] image pub_key.der fw_version\n", argv[0]);
184186
printf(" - or - ");
@@ -196,10 +198,20 @@ int main(int argc, char** argv)
196198
sign = SIGN_ECC256;
197199
sign_str = "ECC256";
198200
}
201+
else if (strcmp(argv[i], "--rsa2048enc") == 0) {
202+
sign = SIGN_RSA2048;
203+
sign_str = "RSA2048ENC";
204+
sign_wenc = 1;
205+
}
199206
else if (strcmp(argv[i], "--rsa2048") == 0) {
200207
sign = SIGN_RSA2048;
201208
sign_str = "RSA2048";
202209
}
210+
else if (strcmp(argv[i], "--rsa4096enc") == 0) {
211+
sign = SIGN_RSA4096;
212+
sign_str = "RSA4096ENC";
213+
sign_wenc = 1;
214+
}
203215
else if (strcmp(argv[i], "--rsa4096") == 0) {
204216
sign = SIGN_RSA4096;
205217
sign_str = "RSA4096";
@@ -585,7 +597,7 @@ int main(int argc, char** argv)
585597
}
586598

587599
/* Sign the digest */
588-
ret = NOT_COMPILED_IN; /* default erorr */
600+
ret = NOT_COMPILED_IN; /* default error */
589601
signature = malloc(signature_sz);
590602
if (signature == NULL) {
591603
printf("Signature malloc error!\n");
@@ -614,7 +626,20 @@ int main(int argc, char** argv)
614626
}
615627
else if (sign == SIGN_RSA2048 || sign == SIGN_RSA4096) {
616628
#ifndef NO_RSA
617-
ret = wc_RsaSSL_Sign(digest, digest_sz, signature, signature_sz, &key.rsa, &rng);
629+
uint32_t enchash_sz = digest_sz;
630+
uint8_t* enchash = digest;
631+
if (sign_wenc) {
632+
/* add ASN.1 signature encoding */
633+
int hashOID = 0;
634+
if (hash_algo == HASH_SHA256)
635+
hashOID = SHA256h;
636+
else if (hash_algo == HASH_SHA3)
637+
hashOID = SHA3_384h;
638+
enchash_sz = wc_EncodeSignature(buf, digest, digest_sz, hashOID);
639+
enchash = buf;
640+
}
641+
ret = wc_RsaSSL_Sign(enchash, enchash_sz, signature, signature_sz,
642+
&key.rsa, &rng);
618643
wc_FreeRsaKey(&key.rsa);
619644
if (ret > 0) {
620645
signature_sz = ret;

0 commit comments

Comments
 (0)