Skip to content

Commit 918fdc5

Browse files
dgarskedanielinux
authored andcommitted
Added keygen --der option to allow ECC private key as ASN.1/DER. Added sign tool ECC key load support for ASN.1/DER private key (default is raw pub x/y, priv d). Refactored sign tool RSA/ECC logic to consolidate code and allow proper "auto" detection for different RSA key sizes.
1 parent 0f8f30d commit 918fdc5

File tree

4 files changed

+352
-383
lines changed

4 files changed

+352
-383
lines changed

docs/Signing.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ Two options are supported:
4949

5050
- `-g privkey.der` to generate a new keypair, add the public key to the keystore and save the private key in a new file `privkey.der`
5151
- `-i existing.der` to import an existing public key from `existing.der`
52+
- `--der` save generated private key in DER format.
5253

5354
Arguments are not exclusive, and can be repeated more than once to populate a keystore with multiple keys.
5455

55-
One option must be specified to select the algorithm enabled in the keystore (e.g. `--ed25519` or `--rsa3072`. See the section "Public key signature options" for the sign tool for the available options.
56+
One option must be specified to select the algorithm enabled in the keystore (e.g. `--ed25519` or `--rsa3072`). See the section "Public key signature options" for the sign tool for the available options.
5657

5758
The files generate by the keygen tool is the following:
5859

@@ -175,6 +176,9 @@ is provided:
175176
`BASE_SIGNED_IMG.BIN` and the new image signed starting from `IMAGE.BIN`. The
176177
result is stored in a file ending in `_signed_diff.bin`.
177178

179+
The compression scheme used is Bentley–McIlroy.
180+
181+
178182
#### Policy signing (for sealing/unsealing with a TPM)
179183

180184
Provides a PCR mask and digest to be signed and included in the header. The signing key is used to sign the digest.

tools/keytools/keygen.c

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@
107107
/* Globals */
108108
static FILE *fpub, *fpub_image;
109109
static int force = 0;
110+
#if defined(WOLFBOOT_RENESAS_RSIP) || \
111+
defined(WOLFBOOT_RENESAS_TSIP) || \
112+
defined(WOLFBOOT_RENESAS_SCEPROTECT)
113+
static int saveAsDer = 1; /* For Renesas PKA default to save as DER/ASN.1 */
114+
#else
115+
static int saveAsDer = 0;
116+
#endif
110117
static WC_RNG rng;
111118

112119
#ifndef KEYSLOT_MAX_PUBKEY_SIZE
@@ -130,11 +137,14 @@ const char Cfile_Banner[]="/* Keystore file for wolfBoot, automatically generate
130137
" * used by wolfBoot to verify the updates.\n"
131138
" */"
132139
"\n#include <stdint.h>\n#include \"wolfboot/wolfboot.h\"\n#include \"keystore.h\"\n"
140+
#if defined(WOLFBOOT_RENESAS_TSIP) || defined(WOLFBOOT_RENESAS_RSIP)
141+
"#include \"user_settings.h\"\n"
133142
#if defined(WOLFBOOT_RENESAS_TSIP)
134143
"#include \"key_data.h\"\n"
135144
#elif defined(WOLFBOOT_RENESAS_RSIP)
136145
"#include \"rsa_pub.h\"\n"
137146
#endif
147+
#endif
138148
"#ifdef WOLFBOOT_NO_SIGN\n\t#define NUM_PUBKEYS 0\n#else\n\n"
139149
"#if !defined(KEYSTORE_ANY) && (KEYSTORE_PUBKEY_SIZE != KEYSTORE_PUBKEY_SIZE_%s)\n\t"
140150
"#error Key algorithm mismatch. Remove old keys via 'make keysclean'\n"
@@ -143,7 +153,7 @@ const char Cfile_Banner[]="/* Keystore file for wolfBoot, automatically generate
143153
const char Store_hdr[] = "\n"
144154
"#if defined(__APPLE__) && defined(__MACH__)\n"
145155
"#define KEYSTORE_SECTION __attribute__((section (\"__KEYSTORE,__keystore\")))\n"
146-
"#elif defined(__CCRX__)\n"
156+
"#elif defined(__CCRX__) /* Renesas RX */\n"
147157
"#define KEYSTORE_SECTION\n"
148158
"#elif defined(TARGET_x86_64_efi)\n"
149159
"#define KEYSTORE_SECTION\n"
@@ -153,14 +163,6 @@ const char Store_hdr[] = "\n"
153163
"#define NUM_PUBKEYS %d\n"
154164
"const KEYSTORE_SECTION struct keystore_slot PubKeys[NUM_PUBKEYS] = {\n\n";
155165
const char Slot_hdr[] =
156-
#if defined(WOLFBOOT_RENESAS_RSIP)
157-
"\t#if !defined(WOLFBOOT_RENESAS_RSIP)\n"
158-
#endif
159-
"\t/* Key associated to file '%s' */\n"
160-
"\t{\n\t\t.slot_id = %d,\n\t\t.key_type = %s,\n"
161-
"\t\t.part_id_mask = 0x%08X,\n\t\t.pubkey_size = %s,\n"
162-
"\t\t.pubkey = {\n\t\t\t";
163-
const char Slot_hdr_int_size[] =
164166
"\t /* Key associated to file '%s' */\n"
165167
"\t{\n\t\t.slot_id = %d,\n\t\t.key_type = %s,\n"
166168
"\t\t.part_id_mask = 0x%08X,\n\t\t.pubkey_size = %u,\n"
@@ -174,8 +176,8 @@ const char Slot_hdr_int_size[] =
174176
#endif
175177
"\t\t\t";
176178
const char Pubkey_footer[] =
177-
#if defined(WOLFBOOT_RENESAS_RSIP) ||\
178-
defined(WOLFBOOT_RENESAS_TSIP) ||\
179+
#if defined(WOLFBOOT_RENESAS_RSIP) || \
180+
defined(WOLFBOOT_RENESAS_TSIP) || \
179181
defined(WOLFBOOT_RENESAS_SCEPROTECT)
180182
"\n\t#endif\n"
181183
#endif
@@ -251,8 +253,9 @@ const char Keystore_API[] =
251253
static void usage(const char *pname) /* implies exit */
252254
{
253255
printf("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 "
254-
"| --ecc521 | --rsa2048 | --rsa3072 "
255-
"| --rsa4096 ] [-g privkey] [-i pubkey] [-keystoreDir dir] [--id {list}] \n", pname);
256+
"| --ecc521 | --rsa2048 | --rsa3072 | --rsa4096 ] "
257+
"[-g privkey] [-i pubkey] [-keystoreDir dir] "
258+
"[--id {list}] [--der]\n", pname);
256259
exit(125);
257260
}
258261

@@ -373,10 +376,7 @@ void keystore_add(uint32_t ktype, uint8_t *key, uint32_t sz, const char *keyfile
373376
struct keystore_slot sl;
374377
size_t slot_size;
375378

376-
if (ktype == KEYGEN_RSA2048 || ktype == KEYGEN_RSA3072 || ktype == KEYGEN_RSA4096)
377-
fprintf(fpub, Slot_hdr_int_size, keyfile, id_slot, KType[ktype], id_mask, sz);
378-
else
379-
fprintf(fpub, Slot_hdr, keyfile, id_slot, KType[ktype], id_mask, KSize[ktype]);
379+
fprintf(fpub, Slot_hdr, keyfile, id_slot, KType[ktype], id_mask, sz);
380380
fwritekey(key, sz, fpub);
381381
fprintf(fpub, Pubkey_footer);
382382
fprintf(fpub, Slot_footer);
@@ -450,11 +450,14 @@ static void keygen_rsa(const char *keyfile, int kbits, uint32_t id_mask)
450450
static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size,
451451
uint32_t id_mask)
452452
{
453+
int ret;
453454
ecc_key k;
454455
uint8_t Qx[MAX_ECC_KEY_SIZE], Qy[MAX_ECC_KEY_SIZE], d[MAX_ECC_KEY_SIZE];
455456
uint32_t qxsize = ecc_key_size,
456457
qysize = ecc_key_size,
457458
dsize = ecc_key_size;
459+
uint8_t priv_der[ECC_BUFSIZE];
460+
int privlen;
458461
uint8_t k_buffer[2 * MAX_ECC_KEY_SIZE];
459462
FILE *fpriv;
460463

@@ -465,9 +468,17 @@ static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size,
465468
exit(1);
466469
}
467470

471+
ret = wc_EccKeyToDer(&k, priv_der, (word32)sizeof(priv_der));
472+
if (ret <= 0) {
473+
fprintf(stderr, "Unable to export private key to DER\n");
474+
exit(2);
475+
}
476+
privlen = ret;
477+
ret = 0;
478+
468479
if (wc_ecc_export_private_raw(&k, Qx, &qxsize, Qy, &qysize, d, &dsize) != 0)
469480
{
470-
fprintf(stderr, "Unable to export private key to DER\n");
481+
fprintf(stderr, "Unable to export private key to raw\n");
471482
exit(2);
472483
}
473484

@@ -486,12 +497,19 @@ static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size,
486497
exit(3);
487498
}
488499

489-
490-
fwrite(Qx, qxsize, 1, fpriv);
491-
fwrite(Qy, qysize, 1, fpriv);
492-
fwrite(d, dsize, 1, fpriv);
500+
if (saveAsDer) {
501+
/* save file as standard ASN.1 / DER */
502+
fwrite(priv_der, privlen, 1, fpriv);
503+
}
504+
else {
505+
/* save file as RAW public X/Y and private K */
506+
fwrite(Qx, qxsize, 1, fpriv);
507+
fwrite(Qy, qysize, 1, fpriv);
508+
fwrite(d, dsize, 1, fpriv);
509+
}
493510
fclose(fpriv);
494-
memcpy(k_buffer, Qx, ecc_key_size);
511+
512+
memcpy(k_buffer, Qx, ecc_key_size);
495513
memcpy(k_buffer + ecc_key_size, Qy, ecc_key_size);
496514

497515
if (ecc_key_size == 32)
@@ -974,6 +992,9 @@ int main(int argc, char** argv)
974992
else if (strcmp(argv[i], "--force") == 0) {
975993
force = 1;
976994
}
995+
else if (strcmp(argv[i], "--der") == 0) {
996+
saveAsDer = 1;
997+
}
977998
else if (strcmp(argv[i], "-g") == 0) {
978999
key_gen_check(argv[i + 1]);
9791000
i++;

0 commit comments

Comments
 (0)