Skip to content

Commit 9247787

Browse files
committed
keygen: zero private material on all errors
1 parent 4a007ab commit 9247787

1 file changed

Lines changed: 77 additions & 30 deletions

File tree

tools/keytools/keygen.c

Lines changed: 77 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -615,40 +615,48 @@ static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size,
615615
uint8_t priv_der[ECC_BUFSIZE];
616616
int privlen;
617617
uint8_t k_buffer[2 * MAX_ECC_KEY_SIZE];
618-
FILE *fpriv;
618+
FILE *fpriv = NULL;
619+
int exit_code = 0;
620+
int key_init = 0;
619621

620622
wc_ecc_init(&k);
623+
key_init = 1;
621624

622625
if (wc_ecc_make_key(&rng, ecc_key_size, &k) != 0) {
623626
fprintf(stderr, "Unable to create ecc key\n");
624-
exit(1);
627+
exit_code = 1;
628+
goto cleanup;
625629
}
626630

627631
ret = wc_EccKeyToDer(&k, priv_der, (word32)sizeof(priv_der));
628632
if (ret <= 0) {
629633
fprintf(stderr, "Unable to export private key to DER\n");
630-
exit(2);
634+
exit_code = 2;
635+
goto cleanup;
631636
}
632637
privlen = ret;
633638
ret = 0;
634639

635640
if (wc_ecc_export_private_raw(&k, Qx, &qxsize, Qy, &qysize, d, &dsize) != 0)
636641
{
637642
fprintf(stderr, "Unable to export private key to raw\n");
638-
exit(2);
643+
exit_code = 2;
644+
goto cleanup;
639645
}
640646

641647
if (wc_ecc_export_public_raw(&k, Qx, &qxsize, Qy, &qysize ) != 0)
642648
{
643649
fprintf(stderr, "Unable to export public key\n");
644-
exit(3);
650+
exit_code = 3;
651+
goto cleanup;
645652
}
646653

647654
fpriv = fopen(priv_fname, "wb");
648655
if (fpriv == NULL) {
649656
fprintf(stderr, "Unable to open file '%s' for writing: %s", priv_fname,
650657
strerror(errno));
651-
exit(3);
658+
exit_code = 3;
659+
goto cleanup;
652660
}
653661

654662
if (saveAsDer) {
@@ -683,19 +691,28 @@ static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size,
683691
if (ret < 0) {
684692
fprintf(stderr, "Unable to export public key to DER, ret=%d\n",
685693
ret);
686-
exit(4);
694+
exit_code = 4;
695+
goto cleanup;
687696
}
688697
if (export_pubkey_file(priv_fname, priv_der, pubOutLen) != 0) {
689698
fprintf(stderr, "Unable to export public key to file\n");
690-
exit(4);
699+
exit_code = 4;
700+
goto cleanup;
691701
}
692702
ret = 0;
693703
}
694704

695-
wc_ecc_free(&k);
705+
cleanup:
706+
if (fpriv != NULL)
707+
fclose(fpriv);
708+
if (key_init)
709+
wc_ecc_free(&k);
696710
wc_ForceZero(d, sizeof(d));
697711
wc_ForceZero(priv_der, sizeof(priv_der));
698712

713+
if (exit_code != 0)
714+
exit(exit_code);
715+
699716
memcpy(k_buffer, Qx, ecc_key_size);
700717
memcpy(k_buffer + ecc_key_size, Qy, ecc_key_size);
701718

@@ -1044,6 +1061,8 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
10441061
int ml_dsa_priv_len = 0;
10451062
int ml_dsa_pub_len = 0;
10461063
int ml_dsa_level = ML_DSA_LEVEL;
1064+
int exit_code = 0;
1065+
int key_init = 0;
10471066
char * env_ml_dsa_level = getenv("ML_DSA_LEVEL");
10481067
if (env_ml_dsa_level != NULL) {
10491068
ml_dsa_level = atoi(env_ml_dsa_level);
@@ -1054,29 +1073,34 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
10541073
ret = wc_MlDsaKey_Init(&key, NULL, INVALID_DEVID);
10551074
if (ret != 0) {
10561075
fprintf(stderr, "error: wc_MlDsaKey_Init returned %d\n", ret);
1057-
exit(1);
1076+
exit_code = 1;
1077+
goto cleanup;
10581078
}
1079+
key_init = 1;
10591080

10601081
ret = wc_MlDsaKey_SetParams(&key, ml_dsa_level);
10611082
if (ret != 0) {
10621083
fprintf(stderr, "error: wc_MlDsaKey_SetParams(%d) returned %d\n",
10631084
ml_dsa_level, ret);
1064-
exit(1);
1085+
exit_code = 1;
1086+
goto cleanup;
10651087
}
10661088

10671089
/* Make the key pair. */
10681090
ret = wc_MlDsaKey_MakeKey(&key, &rng);
10691091
if (ret != 0) {
10701092
fprintf(stderr, "error: wc_MlDsaKey_MakeKey returned %d\n", ret);
1071-
exit(1);
1093+
exit_code = 1;
1094+
goto cleanup;
10721095
}
10731096

10741097
/* Get the ML-DSA public key length. */
10751098
ret = wc_MlDsaKey_GetPubLen(&key, &ml_dsa_pub_len);
10761099
if (ret != 0 || ml_dsa_pub_len <= 0) {
10771100
printf("error: wc_MlDsaKey_GetPrivLen returned %d\n",
10781101
ret);
1079-
exit(1);
1102+
exit_code = 1;
1103+
goto cleanup;
10801104
}
10811105
printf("info: ml-dsa public key length: %d\n", ml_dsa_pub_len);
10821106

@@ -1086,14 +1110,16 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
10861110
if (ret != 0 || ml_dsa_priv_len <= 0) {
10871111
printf("error: wc_MlDsaKey_GetPrivLen returned %d\n",
10881112
ret);
1089-
exit(1);
1113+
exit_code = 1;
1114+
goto cleanup;
10901115
}
10911116
printf("info: ml-dsa private key length: %d\n", ml_dsa_priv_len);
10921117

10931118
if (ml_dsa_priv_len <= ml_dsa_pub_len) {
10941119
printf("error: ml-dsa: unexpected key lengths: %d, %d",
10951120
ml_dsa_priv_len, ml_dsa_pub_len);
1096-
exit(1);
1121+
exit_code = 1;
1122+
goto cleanup;
10971123
}
10981124
else {
10991125
ml_dsa_priv_len -= ml_dsa_pub_len;
@@ -1102,7 +1128,8 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
11021128
priv = malloc(ml_dsa_priv_len);
11031129
if (priv == NULL) {
11041130
fprintf(stderr, "error: malloc(%d) failed\n", ml_dsa_priv_len);
1105-
exit(1);
1131+
exit_code = 1;
1132+
goto cleanup;
11061133
}
11071134

11081135
/* Set the expected key lengths. */
@@ -1112,33 +1139,38 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
11121139
ret = wc_MlDsaKey_ExportPubRaw(&key, pub, &pub_len);
11131140
if (ret != 0) {
11141141
fprintf(stderr, "error: wc_MlDsaKey_ExportPubRaw returned %d\n", ret);
1115-
exit(1);
1142+
exit_code = 1;
1143+
goto cleanup;
11161144
}
11171145

11181146
ret = wc_MlDsaKey_ExportPrivRaw(&key, priv, &priv_len);
11191147
if (ret != 0) {
11201148
fprintf(stderr, "error: wc_MlDsaKey_ExportPrivRaw returned %d\n", ret);
1121-
exit(1);
1149+
exit_code = 1;
1150+
goto cleanup;
11221151
}
11231152

11241153
if ((int)pub_len != ml_dsa_pub_len) {
11251154
fprintf(stderr, "error: wc_MlDsaKey_ExportPubRaw returned pub_len=%d, " \
11261155
"expected %d\n", pub_len, ml_dsa_pub_len);
1127-
exit(1);
1156+
exit_code = 1;
1157+
goto cleanup;
11281158
}
11291159

11301160
if ((int) priv_len != ml_dsa_priv_len) {
11311161
fprintf(stderr, "error: ml_dsa priv key mismatch: got %d " \
11321162
"bytes, expected %d\n", priv_len, ml_dsa_priv_len);
1133-
exit(1);
1163+
exit_code = 1;
1164+
goto cleanup;
11341165
}
11351166

11361167
fpriv = fopen(priv_fname, "wb");
11371168

11381169
if (fpriv == NULL) {
11391170
fprintf(stderr, "error: fopen(%s) failed: %s",
11401171
priv_fname, strerror(errno));
1141-
exit(1);
1172+
exit_code = 1;
1173+
goto cleanup;
11421174
}
11431175

11441176
fwrite(priv, priv_len, 1, fpriv);
@@ -1165,14 +1197,16 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
11651197
break;
11661198
default:
11671199
fprintf(stderr, "Error: Unsupported ML DSA level\n");
1168-
exit(1);
1200+
exit_code = 1;
1201+
goto cleanup;
11691202
break;
11701203
}
11711204
pubDer = (uint8_t*)malloc(pubDerSz);
11721205
if (pubDer == NULL) {
11731206
fprintf(stderr,
11741207
"Error: Failed to allocate memory for DER export\n");
1175-
exit(1);
1208+
exit_code = 1;
1209+
goto cleanup;
11761210
}
11771211

11781212
/* Export public key in DER format */
@@ -1182,12 +1216,16 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
11821216
if (pubOutLen < 0) {
11831217
fprintf(stderr, "Unable to export public key to DER, ret=%d\n",
11841218
pubOutLen);
1185-
exit(1);
1219+
free(pubDer);
1220+
exit_code = 1;
1221+
goto cleanup;
11861222
}
11871223

11881224
if (export_pubkey_file(priv_fname, pubDer, pubOutLen) != 0) {
11891225
fprintf(stderr, "Unable to export public key to file\n");
1190-
exit(1);
1226+
free(pubDer);
1227+
exit_code = 1;
1228+
goto cleanup;
11911229
}
11921230

11931231
free(pubDer);
@@ -1197,17 +1235,26 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
11971235
if (export_pubkey_file(priv_fname, pub,
11981236
KEYSTORE_PUBKEY_SIZE_ML_DSA) != 0) {
11991237
fprintf(stderr, "Unable to export public key to file\n");
1200-
exit(1);
1238+
exit_code = 1;
1239+
goto cleanup;
12011240
}
12021241
}
12031242
}
12041243

12051244
keystore_add(AUTH_KEY_ML_DSA, pub, pub_len, priv_fname, id_mask);
12061245

1207-
wc_MlDsaKey_Free(&key);
1208-
wc_ForceZero(priv, priv_len);
1209-
free(priv);
1210-
priv = NULL;
1246+
cleanup:
1247+
if (fpriv != NULL)
1248+
fclose(fpriv);
1249+
if (key_init)
1250+
wc_MlDsaKey_Free(&key);
1251+
if (priv != NULL) {
1252+
wc_ForceZero(priv, priv_len);
1253+
free(priv);
1254+
priv = NULL;
1255+
}
1256+
if (exit_code != 0)
1257+
exit(exit_code);
12111258
}
12121259

12131260
static void key_gen_check(const char *kfilename)

0 commit comments

Comments
 (0)