mirror of https://github.com/wolfSSL/wolfBoot.git
F-14301, F-14302: keep no libc stdio copy of key material;
The keytools read and write private keys through fully buffered stdio streams: for key files smaller than the stdio buffer, libc copies the raw key bytes into its internal FILE buffer, and fclose() frees that buffer without scrubbing it, so a copy of every key survives the explicit zero_and_free()/wc_ForceZero() wipes. Open every secret-material stream unbuffered with setvbuf(f, NULL, _IONBF, 0) right after fopen(): - sign.c load_key(): the private key file. Also close the stream on the short-read failure path, which previously leaked it. - sign.c make_header_ex(): the firmware encryption key/IV file. - keygen.c: the five private-key write sites (RSA, ECC, Ed25519, Ed448, ML-DSA). - lms_common.h / xmss_common.h: the LMS/XMSS private-state write, verify-read and read callbacks. Public-key export streams are left buffered: not secret. Host-side hardening only: whoever can read the tool heap can read the key file too.pull/913/head
parent
41b047ad49
commit
b896caeea0
|
|
@ -607,6 +607,8 @@ static void keygen_rsa(const char *keyfile, int kbits, uint32_t id_mask,
|
|||
exit_code = 4;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private key. */
|
||||
setvbuf(fpriv, NULL, _IONBF, 0);
|
||||
fwrite(priv_der, privlen, 1, fpriv);
|
||||
fclose(fpriv);
|
||||
fpriv = NULL;
|
||||
|
|
@ -687,6 +689,8 @@ static void keygen_ecc(const char *priv_fname, uint16_t ecc_key_size,
|
|||
exit_code = 3;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private key. */
|
||||
setvbuf(fpriv, NULL, _IONBF, 0);
|
||||
|
||||
if (saveAsDer) {
|
||||
/* save file as standard ASN.1 / DER */
|
||||
|
|
@ -794,6 +798,8 @@ static void keygen_ed25519(const char *privkey, uint32_t id_mask)
|
|||
exit_code = 3;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private key. */
|
||||
setvbuf(fpriv, NULL, _IONBF, 0);
|
||||
fwrite(priv, 32, 1, fpriv);
|
||||
fwrite(pub, 32, 1, fpriv);
|
||||
fclose(fpriv);
|
||||
|
|
@ -855,6 +861,8 @@ static void keygen_ed448(const char *privkey, uint32_t id_mask)
|
|||
exit_code = 3;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private key. */
|
||||
setvbuf(fpriv, NULL, _IONBF, 0);
|
||||
fwrite(priv, ED448_KEY_SIZE, 1, fpriv);
|
||||
fwrite(pub, ED448_PUB_KEY_SIZE, 1, fpriv);
|
||||
fclose(fpriv);
|
||||
|
|
@ -1243,6 +1251,8 @@ static void keygen_ml_dsa(const char *priv_fname, uint32_t id_mask)
|
|||
exit_code = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private key. */
|
||||
setvbuf(fpriv, NULL, _IONBF, 0);
|
||||
|
||||
fwrite(priv, priv_len, 1, fpriv);
|
||||
fwrite(pub, pub_len, 1, fpriv);
|
||||
|
|
|
|||
|
|
@ -709,6 +709,8 @@ static uint8_t *load_key(uint8_t **key_buffer, uint32_t *key_buffer_sz,
|
|||
printf("Open key file %s failed\n", key_file);
|
||||
goto failure;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private key bytes. */
|
||||
setvbuf(f, NULL, _IONBF, 0);
|
||||
fseek(f, 0, SEEK_END);
|
||||
*key_buffer_sz = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
|
@ -717,6 +719,8 @@ static uint8_t *load_key(uint8_t **key_buffer, uint32_t *key_buffer_sz,
|
|||
io_sz = (int)fread(*key_buffer, 1, *key_buffer_sz, f);
|
||||
if (io_sz != (int)*key_buffer_sz) {
|
||||
printf("Key file read error!\n");
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
|
@ -2480,6 +2484,8 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
|
|||
CMD.encrypt_key_file, strerror(errno));
|
||||
goto failure;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the key/IV bytes. */
|
||||
setvbuf(fek, NULL, _IONBF, 0);
|
||||
ret = (int)fread(key, 1, keySz, fek);
|
||||
if (ret != keySz) {
|
||||
fprintf(stderr, "Error reading key from %s\n", CMD.encrypt_key_file);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ static int lms_write_key(const byte * priv, word32 privSz, void * context)
|
|||
return WC_LMS_RC_WRITE_FAIL;
|
||||
}
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private state. */
|
||||
setvbuf(file, NULL, _IONBF, 0);
|
||||
|
||||
n_write = fwrite(priv, 1, privSz, file);
|
||||
|
||||
|
|
@ -74,6 +76,8 @@ static int lms_write_key(const byte * priv, word32 privSz, void * context)
|
|||
fprintf(stderr, "error: fopen(%s, \"r+\") failed.\n", filename);
|
||||
return WC_LMS_RC_WRITE_FAIL;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private state. */
|
||||
setvbuf(file, NULL, _IONBF, 0);
|
||||
|
||||
XMEMSET(buff, 0, n_write);
|
||||
|
||||
|
|
@ -128,6 +132,8 @@ static int lms_read_key(byte * priv, word32 privSz, void * context)
|
|||
fprintf(stderr, "error: fopen(%s, \"rb\") failed\n", filename);
|
||||
return WC_LMS_RC_READ_FAIL;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private state. */
|
||||
setvbuf(file, NULL, _IONBF, 0);
|
||||
|
||||
n_read = fread(priv, 1, privSz, file);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ static enum wc_XmssRc xmss_write_key(const byte * priv, word32 privSz, void * co
|
|||
return WC_XMSS_RC_WRITE_FAIL;
|
||||
}
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private state. */
|
||||
setvbuf(file, NULL, _IONBF, 0);
|
||||
|
||||
n_write = fwrite(priv, 1, privSz, file);
|
||||
|
||||
|
|
@ -74,6 +76,8 @@ static enum wc_XmssRc xmss_write_key(const byte * priv, word32 privSz, void * co
|
|||
fprintf(stderr, "error: fopen(%s, \"r+\") failed.\n", filename);
|
||||
return WC_XMSS_RC_WRITE_FAIL;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private state. */
|
||||
setvbuf(file, NULL, _IONBF, 0);
|
||||
|
||||
buff = malloc(privSz);
|
||||
if (buff == NULL) {
|
||||
|
|
@ -130,6 +134,8 @@ static enum wc_XmssRc xmss_read_key(byte * priv, word32 privSz, void * context)
|
|||
fprintf(stderr, "error: fopen(%s, \"rb\") failed\n", filename);
|
||||
return WC_XMSS_RC_READ_FAIL;
|
||||
}
|
||||
/* Unbuffered: keep no libc-owned copy of the private state. */
|
||||
setvbuf(file, NULL, _IONBF, 0);
|
||||
|
||||
n_read = fread(priv, 1, privSz, file);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue