diff --git a/cmdgen.c b/cmdgen.c index 50f99f701..5b0e54d9a 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -667,7 +667,7 @@ int main(int argc, char **argv) return 1; } random_add_heavynoise(entropy, bits / 8); - memset(entropy, 0, bits/8); + smemclr(entropy, bits/8); sfree(entropy); if (keytype == DSA) { @@ -860,7 +860,7 @@ int main(int argc, char **argv) return 1; } if (passphrase) { - memset(passphrase, 0, strlen(passphrase)); + smemclr(passphrase, strlen(passphrase)); sfree(passphrase); } passphrase = dupstr(p->prompts[0]->result); @@ -1035,7 +1035,7 @@ int main(int argc, char **argv) } if (passphrase) { - memset(passphrase, 0, strlen(passphrase)); + smemclr(passphrase, strlen(passphrase)); sfree(passphrase); } diff --git a/cmdline.c b/cmdline.c index 2c3b7ce5c..a4c916010 100644 --- a/cmdline.c +++ b/cmdline.c @@ -63,7 +63,7 @@ void cmdline_cleanup(void) int pri; if (cmdline_password) { - memset(cmdline_password, 0, strlen(cmdline_password)); + smemclr(cmdline_password, strlen(cmdline_password)); sfree(cmdline_password); cmdline_password = NULL; } @@ -106,7 +106,7 @@ int cmdline_get_passwd_input(prompts_t *p, unsigned char *in, int inlen) { return 0; prompt_set_result(p->prompts[0], cmdline_password); - memset(cmdline_password, 0, strlen(cmdline_password)); + smemclr(cmdline_password, strlen(cmdline_password)); sfree(cmdline_password); cmdline_password = NULL; tried_once = 1; @@ -368,7 +368,7 @@ int cmdline_process_param(char *p, char *value, int need_save, Conf *conf) /* Assuming that `value' is directly from argv, make a good faith * attempt to trample it, to stop it showing up in `ps' output * on Unix-like systems. Not guaranteed, of course. */ - memset(value, 0, strlen(value)); + smemclr(value, strlen(value)); } } diff --git a/import.c b/import.c index 55e3be27b..05cfdc147 100644 --- a/import.c +++ b/import.c @@ -358,7 +358,7 @@ static struct openssh_key *load_openssh_key(const Filename *filename, errmsg = "unrecognised key type"; goto error; } - memset(line, 0, strlen(line)); + smemclr(line, strlen(line)); sfree(line); line = NULL; @@ -442,13 +442,13 @@ static struct openssh_key *load_openssh_key(const Filename *filename, memcpy(ret->keyblob + ret->keyblob_len, out, len); ret->keyblob_len += len; - memset(out, 0, sizeof(out)); + smemclr(out, sizeof(out)); } p++; } } - memset(line, 0, strlen(line)); + smemclr(line, strlen(line)); sfree(line); line = NULL; } @@ -463,23 +463,23 @@ static struct openssh_key *load_openssh_key(const Filename *filename, goto error; } - memset(base64_bit, 0, sizeof(base64_bit)); + smemclr(base64_bit, sizeof(base64_bit)); if (errmsg_p) *errmsg_p = NULL; return ret; error: if (line) { - memset(line, 0, strlen(line)); + smemclr(line, strlen(line)); sfree(line); line = NULL; } - memset(base64_bit, 0, sizeof(base64_bit)); + smemclr(base64_bit, sizeof(base64_bit)); if (ret) { if (ret->keyblob) { - memset(ret->keyblob, 0, ret->keyblob_size); + smemclr(ret->keyblob, ret->keyblob_size); sfree(ret->keyblob); } - memset(ret, 0, sizeof(*ret)); + smemclr(ret, sizeof(*ret)); sfree(ret); } if (errmsg_p) *errmsg_p = errmsg; @@ -494,9 +494,9 @@ int openssh_encrypted(const Filename *filename) if (!key) return 0; ret = key->encrypted; - memset(key->keyblob, 0, key->keyblob_size); + smemclr(key->keyblob, key->keyblob_size); sfree(key->keyblob); - memset(key, 0, sizeof(*key)); + smemclr(key, sizeof(*key)); sfree(key); return ret; } @@ -564,8 +564,8 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, aes_free_context(ctx); } - memset(&md5c, 0, sizeof(md5c)); - memset(keybuf, 0, sizeof(keybuf)); + smemclr(&md5c, sizeof(md5c)); + smemclr(keybuf, sizeof(keybuf)); } /* @@ -698,12 +698,12 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, error: if (blob) { - memset(blob, 0, blobsize); + smemclr(blob, blobsize); sfree(blob); } - memset(key->keyblob, 0, key->keyblob_size); + smemclr(key->keyblob, key->keyblob_size); sfree(key->keyblob); - memset(key, 0, sizeof(*key)); + smemclr(key, sizeof(*key)); sfree(key); if (errmsg_p) *errmsg_p = errmsg; return retval; @@ -911,8 +911,8 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, */ des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen); - memset(&md5c, 0, sizeof(md5c)); - memset(keybuf, 0, sizeof(keybuf)); + smemclr(&md5c, sizeof(md5c)); + smemclr(keybuf, sizeof(keybuf)); } /* @@ -936,19 +936,19 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, error: if (outblob) { - memset(outblob, 0, outlen); + smemclr(outblob, outlen); sfree(outblob); } if (spareblob) { - memset(spareblob, 0, sparelen); + smemclr(spareblob, sparelen); sfree(spareblob); } if (privblob) { - memset(privblob, 0, privlen); + smemclr(privblob, privlen); sfree(privblob); } if (pubblob) { - memset(pubblob, 0, publen); + smemclr(pubblob, publen); sfree(pubblob); } return ret; @@ -1067,7 +1067,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, errmsg = "file does not begin with ssh.com key header"; goto error; } - memset(line, 0, strlen(line)); + smemclr(line, strlen(line)); sfree(line); line = NULL; @@ -1112,7 +1112,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, len += line2len - 1; assert(!line[len]); - memset(line2, 0, strlen(line2)); + smemclr(line2, strlen(line2)); sfree(line2); line2 = NULL; } @@ -1158,7 +1158,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, p++; } } - memset(line, 0, strlen(line)); + smemclr(line, strlen(line)); sfree(line); line = NULL; } @@ -1173,16 +1173,16 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, error: if (line) { - memset(line, 0, strlen(line)); + smemclr(line, strlen(line)); sfree(line); line = NULL; } if (ret) { if (ret->keyblob) { - memset(ret->keyblob, 0, ret->keyblob_size); + smemclr(ret->keyblob, ret->keyblob_size); sfree(ret->keyblob); } - memset(ret, 0, sizeof(*ret)); + smemclr(ret, sizeof(*ret)); sfree(ret); } if (errmsg_p) *errmsg_p = errmsg; @@ -1222,9 +1222,9 @@ int sshcom_encrypted(const Filename *filename, char **comment) done: *comment = dupstr(key->comment); - memset(key->keyblob, 0, key->keyblob_size); + smemclr(key->keyblob, key->keyblob_size); sfree(key->keyblob); - memset(key, 0, sizeof(*key)); + smemclr(key, sizeof(*key)); sfree(key); return answer; } @@ -1390,8 +1390,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext, cipherlen); - memset(&md5c, 0, sizeof(md5c)); - memset(keybuf, 0, sizeof(keybuf)); + smemclr(&md5c, sizeof(md5c)); + smemclr(keybuf, sizeof(keybuf)); /* * Hereafter we return WRONG_PASSPHRASE for any parsing @@ -1494,12 +1494,12 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, error: if (blob) { - memset(blob, 0, blobsize); + smemclr(blob, blobsize); sfree(blob); } - memset(key->keyblob, 0, key->keyblob_size); + smemclr(key->keyblob, key->keyblob_size); sfree(key->keyblob); - memset(key, 0, sizeof(*key)); + smemclr(key, sizeof(*key)); sfree(key); if (errmsg_p) *errmsg_p = errmsg; return ret; @@ -1664,8 +1664,8 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext, cipherlen); - memset(&md5c, 0, sizeof(md5c)); - memset(keybuf, 0, sizeof(keybuf)); + smemclr(&md5c, sizeof(md5c)); + smemclr(keybuf, sizeof(keybuf)); } /* @@ -1700,15 +1700,15 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, error: if (outblob) { - memset(outblob, 0, outlen); + smemclr(outblob, outlen); sfree(outblob); } if (privblob) { - memset(privblob, 0, privlen); + smemclr(privblob, privlen); sfree(privblob); } if (pubblob) { - memset(pubblob, 0, publen); + smemclr(pubblob, publen); sfree(pubblob); } return ret; diff --git a/misc.c b/misc.c index 636ca9f39..76e5fab21 100644 --- a/misc.c +++ b/misc.c @@ -124,7 +124,7 @@ void prompt_ensure_result_size(prompt_t *pr, int newlen) */ newbuf = snewn(newlen, char); memcpy(newbuf, pr->result, pr->resultsize); - memset(pr->result, '\0', pr->resultsize); + smemclr(pr->result, pr->resultsize); sfree(pr->result); pr->result = newbuf; pr->resultsize = newlen; @@ -140,7 +140,7 @@ void free_prompts(prompts_t *p) size_t i; for (i=0; i < p->n_prompts; i++) { prompt_t *pr = p->prompts[i]; - memset(pr->result, 0, pr->resultsize); /* burn the evidence */ + smemclr(pr->result, pr->resultsize); /* burn the evidence */ sfree(pr->result); sfree(pr->prompt); sfree(pr); @@ -203,7 +203,7 @@ char *dupcat(const char *s1, ...) void burnstr(char *string) /* sfree(str), only clear it first */ { if (string) { - memset(string, 0, strlen(string)); + smemclr(string, strlen(string)); sfree(string); } } @@ -685,3 +685,43 @@ char const *conf_dest(Conf *conf) else return conf_get_str(conf, CONF_host); } + +#ifndef PLATFORM_HAS_SMEMCLR +/* + * Securely wipe memory. + * + * The actual wiping is no different from what memset would do: the + * point of 'securely' is to try to be sure over-clever compilers + * won't optimise away memsets on variables that are about to be freed + * or go out of scope. See + * https://buildsecurityin.us-cert.gov/bsi-rules/home/g1/771-BSI.html + * + * Some platforms (e.g. Windows) may provide their own version of this + * function. + */ +void smemclr(void *b, size_t n) { + volatile char *vp; + + if (b && n > 0) { + /* + * Zero out the memory. + */ + memset(b, 0, n); + + /* + * Perform a volatile access to the object, forcing the + * compiler to admit that the previous memset was important. + * + * This while loop should in practice run for zero iterations + * (since we know we just zeroed the object out), but in + * theory (as far as the compiler knows) it might range over + * the whole object. (If we had just written, say, '*vp = + * *vp;', a compiler could in principle have 'helpfully' + * optimised the memset into only zeroing out the first byte. + * This should be robust.) + */ + vp = b; + while (*vp) vp++; + } +} +#endif diff --git a/putty.h b/putty.h index dcc80db57..b32b0fa1e 100644 --- a/putty.h +++ b/putty.h @@ -1291,6 +1291,7 @@ int filename_serialise(const Filename *f, void *data); Filename *filename_deserialise(void *data, int maxsize, int *used); char *get_username(void); /* return value needs freeing */ char *get_random_data(int bytes); /* used in cmdgen.c */ +void smemclr(void *b, size_t len); /* * Exports and imports from timing.c. diff --git a/ssh.c b/ssh.c index ef503bf52..1f1a26567 100644 --- a/ssh.c +++ b/ssh.c @@ -3849,7 +3849,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, ret = loadrsakey(s->keyfile, &s->key, passphrase, &error); if (passphrase) { - memset(passphrase, 0, strlen(passphrase)); + smemclr(passphrase, strlen(passphrase)); sfree(passphrase); } if (ret == 1) { @@ -6294,7 +6294,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, assert(ssh->csmac->len <= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace); - memset(keyspace, 0, sizeof(keyspace)); + smemclr(keyspace, sizeof(keyspace)); } logeventf(ssh, "Initialised %.200s client->server encryption", @@ -6360,7 +6360,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, assert(ssh->scmac->len <= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS); ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace); - memset(keyspace, 0, sizeof(keyspace)); + smemclr(keyspace, sizeof(keyspace)); } logeventf(ssh, "Initialised %.200s server->client encryption", ssh->sccipher->text_name); @@ -8151,7 +8151,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, key = ssh2_load_userkey(s->keyfile, passphrase, &error); if (passphrase) { /* burn the evidence */ - memset(passphrase, 0, strlen(passphrase)); + smemclr(passphrase, strlen(passphrase)); sfree(passphrase); } if (key == SSH2_WRONG_PASSPHRASE || key == NULL) { @@ -8730,7 +8730,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, */ /* burn the evidence */ free_prompts(s->cur_prompt); - memset(s->password, 0, strlen(s->password)); + smemclr(s->password, strlen(s->password)); sfree(s->password); ssh_disconnect(ssh, NULL, "Unable to authenticate", SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER, @@ -8746,7 +8746,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * re-enter it if they louse up the new password.) */ if (s->cur_prompt->prompts[0]->result[0]) { - memset(s->password, 0, strlen(s->password)); + smemclr(s->password, strlen(s->password)); /* burn the evidence */ sfree(s->password); s->password = @@ -8813,7 +8813,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, * We don't need the old password any more, in any * case. Burn the evidence. */ - memset(s->password, 0, strlen(s->password)); + smemclr(s->password, strlen(s->password)); sfree(s->password); } else { diff --git a/sshaes.c b/sshaes.c index 2800e021f..97935b7f1 100644 --- a/sshaes.c +++ b/sshaes.c @@ -1157,7 +1157,7 @@ void aes256_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len) aes_setup(&ctx, 16, key, 32); memset(ctx.iv, 0, sizeof(ctx.iv)); aes_encrypt_cbc(blk, len, &ctx); - memset(&ctx, 0, sizeof(ctx)); + smemclr(&ctx, sizeof(ctx)); } void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len) @@ -1166,7 +1166,7 @@ void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len) aes_setup(&ctx, 16, key, 32); memset(ctx.iv, 0, sizeof(ctx.iv)); aes_decrypt_cbc(blk, len, &ctx); - memset(&ctx, 0, sizeof(ctx)); + smemclr(&ctx, sizeof(ctx)); } static const struct ssh2_cipher ssh_aes128_ctr = { diff --git a/ssharcf.c b/ssharcf.c index 6bfbd8959..06f235c5b 100644 --- a/ssharcf.c +++ b/ssharcf.c @@ -75,7 +75,7 @@ static void arcfour_stir(ArcfourContext *ctx) unsigned char *junk = snewn(1536, unsigned char); memset(junk, 0, 1536); arcfour_block(ctx, junk, 1536); - memset(junk, 0, 1536); + smemclr(junk, 1536); sfree(junk); } diff --git a/sshbn.c b/sshbn.c index 484c423f0..999817db4 100644 --- a/sshbn.c +++ b/sshbn.c @@ -148,7 +148,7 @@ void freebn(Bignum b) /* * Burn the evidence, just in case. */ - memset(b, 0, sizeof(b[0]) * (b[0] + 1)); + smemclr(b, sizeof(b[0]) * (b[0] + 1)); sfree(b); } diff --git a/sshdes.c b/sshdes.c index b12a91d51..03d2b3ae4 100644 --- a/sshdes.c +++ b/sshdes.c @@ -858,7 +858,7 @@ void des3_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len) des_key_setup(GET_32BIT_MSB_FIRST(key), GET_32BIT_MSB_FIRST(key + 4), &ourkeys[2]); des_3cbc_decrypt(blk, len, ourkeys); - memset(ourkeys, 0, sizeof(ourkeys)); + smemclr(ourkeys, sizeof(ourkeys)); } void des3_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len) @@ -871,7 +871,7 @@ void des3_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len) des_key_setup(GET_32BIT_MSB_FIRST(key), GET_32BIT_MSB_FIRST(key + 4), &ourkeys[2]); des_3cbc_encrypt(blk, len, ourkeys); - memset(ourkeys, 0, sizeof(ourkeys)); + smemclr(ourkeys, sizeof(ourkeys)); } void des3_decrypt_pubkey_ossh(unsigned char *key, unsigned char *iv, @@ -887,7 +887,7 @@ void des3_decrypt_pubkey_ossh(unsigned char *key, unsigned char *iv, ourkeys[0].iv0 = GET_32BIT_MSB_FIRST(iv); ourkeys[0].iv1 = GET_32BIT_MSB_FIRST(iv+4); des_cbc3_decrypt(blk, len, ourkeys); - memset(ourkeys, 0, sizeof(ourkeys)); + smemclr(ourkeys, sizeof(ourkeys)); } void des3_encrypt_pubkey_ossh(unsigned char *key, unsigned char *iv, @@ -903,7 +903,7 @@ void des3_encrypt_pubkey_ossh(unsigned char *key, unsigned char *iv, ourkeys[0].iv0 = GET_32BIT_MSB_FIRST(iv); ourkeys[0].iv1 = GET_32BIT_MSB_FIRST(iv+4); des_cbc3_encrypt(blk, len, ourkeys); - memset(ourkeys, 0, sizeof(ourkeys)); + smemclr(ourkeys, sizeof(ourkeys)); } static void des_keysetup_xdmauth(unsigned char *keydata, DESContext *dc) diff --git a/sshdss.c b/sshdss.c index 7c95d11b6..6cf5830d5 100644 --- a/sshdss.c +++ b/sshdss.c @@ -20,7 +20,7 @@ static void sha_mpint(SHA_State * s, Bignum b) lenbuf[0] = bignum_byte(b, len); SHA_Bytes(s, lenbuf, 1); } - memset(lenbuf, 0, sizeof(lenbuf)); + smemclr(lenbuf, sizeof(lenbuf)); } static void sha512_mpint(SHA512_State * s, Bignum b) @@ -34,7 +34,7 @@ static void sha512_mpint(SHA512_State * s, Bignum b) lenbuf[0] = bignum_byte(b, len); SHA512_Bytes(s, lenbuf, 1); } - memset(lenbuf, 0, sizeof(lenbuf)); + smemclr(lenbuf, sizeof(lenbuf)); } static void getstring(char **data, int *datalen, char **p, int *length) @@ -575,7 +575,7 @@ static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) SHA512_Bytes(&ss, digest, sizeof(digest)); SHA512_Final(&ss, digest512); - memset(&ss, 0, sizeof(ss)); + smemclr(&ss, sizeof(ss)); /* * Now convert the result into a bignum, and reduce it mod q. @@ -584,7 +584,7 @@ static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen) k = bigmod(proto_k, dss->q); freebn(proto_k); - memset(digest512, 0, sizeof(digest512)); + smemclr(digest512, sizeof(digest512)); /* * Now we have k, so just go ahead and compute the signature. diff --git a/sshmd5.c b/sshmd5.c index 7112d4060..e5187a661 100644 --- a/sshmd5.c +++ b/sshmd5.c @@ -249,7 +249,7 @@ void hmacmd5_key(void *handle, void const *keyv, int len) MD5Init(&keys[1]); MD5Update(&keys[1], foo, 64); - memset(foo, 0, 64); /* burn the evidence */ + smemclr(foo, 64); /* burn the evidence */ } static void hmacmd5_key_16(void *handle, unsigned char *key) diff --git a/sshpubk.c b/sshpubk.c index 88ff17921..c29d8a58a 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -108,7 +108,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7); - memset(keybuf, 0, sizeof(keybuf)); /* burn the evidence */ + smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* @@ -150,7 +150,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, ret = 1; end: - memset(buf, 0, sizeof(buf)); /* burn the evidence */ + smemclr(buf, sizeof(buf)); /* burn the evidence */ return ret; } @@ -358,7 +358,7 @@ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase) MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_encrypt_pubkey(keybuf, estart, p - estart); - memset(keybuf, 0, sizeof(keybuf)); /* burn the evidence */ + smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* @@ -794,14 +794,14 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, hmac_sha1_simple(mackey, 20, macdata, maclen, binary); - memset(mackey, 0, sizeof(mackey)); - memset(&s, 0, sizeof(s)); + smemclr(mackey, sizeof(mackey)); + smemclr(&s, sizeof(s)); } else { SHA_Simple(macdata, maclen, binary); } if (free_macdata) { - memset(macdata, 0, maclen); + smemclr(macdata, maclen); sfree(macdata); } @@ -1116,10 +1116,10 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, SHA_Bytes(&s, passphrase, strlen(passphrase)); SHA_Final(&s, mackey); hmac_sha1_simple(mackey, 20, macdata, maclen, priv_mac); - memset(macdata, 0, maclen); + smemclr(macdata, maclen); sfree(macdata); - memset(mackey, 0, sizeof(mackey)); - memset(&s, 0, sizeof(s)); + smemclr(mackey, sizeof(mackey)); + smemclr(&s, sizeof(s)); } if (passphrase) { @@ -1139,8 +1139,8 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, aes256_encrypt_pubkey(key, priv_blob_encrypted, priv_encrypted_len); - memset(key, 0, sizeof(key)); - memset(&s, 0, sizeof(s)); + smemclr(key, sizeof(key)); + smemclr(&s, sizeof(s)); } fp = f_open(filename, "w", TRUE); @@ -1160,7 +1160,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, fclose(fp); sfree(pub_blob); - memset(priv_blob, 0, priv_blob_len); + smemclr(priv_blob, priv_blob_len); sfree(priv_blob); sfree(priv_blob_encrypted); return 1; diff --git a/sshrsa.c b/sshrsa.c index 0c1b2ef5a..77a6bb250 100644 --- a/sshrsa.c +++ b/sshrsa.c @@ -110,7 +110,7 @@ static void sha512_mpint(SHA512_State * s, Bignum b) lenbuf[0] = bignum_byte(b, len); SHA512_Bytes(s, lenbuf, 1); } - memset(lenbuf, 0, sizeof(lenbuf)); + smemclr(lenbuf, sizeof(lenbuf)); } /* diff --git a/sshsha.c b/sshsha.c index cbe9d78b4..30113511b 100644 --- a/sshsha.c +++ b/sshsha.c @@ -253,7 +253,7 @@ static void sha1_key_internal(void *handle, unsigned char *key, int len) SHA_Init(&keys[1]); SHA_Bytes(&keys[1], foo, 64); - memset(foo, 0, 64); /* burn the evidence */ + smemclr(foo, 64); /* burn the evidence */ } static void sha1_key(void *handle, unsigned char *key) diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 03f285515..241aa6bcd 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -3582,7 +3582,7 @@ int pt_main(int argc, char **argv) if (argc > 1 && !strncmp(argv[1], "---", 3)) { read_dupsession_data(inst, inst->conf, argv[1]); /* Splatter this argument so it doesn't clutter a ps listing */ - memset(argv[1], 0, strlen(argv[1])); + smemclr(argv[1], strlen(argv[1])); } else { /* By default, we bring up the config dialog, rather than launching * a session. This gets set to TRUE if something happens to change diff --git a/windows/winmisc.c b/windows/winmisc.c index f54e8a4d6..2166f4530 100644 --- a/windows/winmisc.c +++ b/windows/winmisc.c @@ -68,6 +68,14 @@ Filename *filename_deserialise(void *vdata, int maxsize, int *used) return filename_from_str(data); } +/* + * Windows implementation of smemclr (see misc.c) using SecureZeroMemory. + */ +void smemclr(void *b, size_t n) { + if (b && n > 0) + SecureZeroMemory(b, n); +} + char *get_username(void) { DWORD namelen; diff --git a/windows/winpgen.c b/windows/winpgen.c index c83d0d20c..ffbeb1a4e 100644 --- a/windows/winpgen.c +++ b/windows/winpgen.c @@ -958,7 +958,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, * Seed the entropy pool */ random_add_heavynoise(state->entropy, state->entropy_size); - memset(state->entropy, 0, state->entropy_size); + smemclr(state->entropy, state->entropy_size); sfree(state->entropy); state->collecting_entropy = FALSE; diff --git a/windows/winpgnt.c b/windows/winpgnt.c index 291593e49..21a69cc00 100644 --- a/windows/winpgnt.c +++ b/windows/winpgnt.c @@ -174,7 +174,7 @@ static void forget_passphrases(void) { while (count234(passphrases) > 0) { char *pp = index234(passphrases, 0); - memset(pp, 0, strlen(pp)); + smemclr(pp, strlen(pp)); delpos234(passphrases, 0); free(pp); } @@ -968,7 +968,7 @@ static void answer_msg(void *msg) MD5Init(&md5c); MD5Update(&md5c, response_source, 48); MD5Final(response_md5, &md5c); - memset(response_source, 0, 48); /* burn the evidence */ + smemclr(response_source, 48); /* burn the evidence */ freebn(response); /* and that evidence */ freebn(challenge); /* yes, and that evidence */ freebn(reqkey.exponent); /* and free some memory ... */ diff --git a/windows/winstuff.h b/windows/winstuff.h index df59631c4..d81515dc7 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -75,6 +75,8 @@ struct FontSpec *fontspec_new(const char *name, #define BOXRESULT (DLGWINDOWEXTRA + sizeof(LONG_PTR)) #define DF_END 0x0001 +#define PLATFORM_HAS_SMEMCLR /* inhibit cross-platform one in misc.c */ + /* * Dynamically linked functions. These come in two flavours: * diff --git a/x11fwd.c b/x11fwd.c index 5b4f76cdc..1e04f542b 100644 --- a/x11fwd.c +++ b/x11fwd.c @@ -264,10 +264,10 @@ void x11_free_display(struct X11Display *disp) sfree(disp->hostname); sfree(disp->unixsocketpath); if (disp->localauthdata) - memset(disp->localauthdata, 0, disp->localauthdatalen); + smemclr(disp->localauthdata, disp->localauthdatalen); sfree(disp->localauthdata); if (disp->remoteauthdata) - memset(disp->remoteauthdata, 0, disp->remoteauthdatalen); + smemclr(disp->remoteauthdata, disp->remoteauthdatalen); sfree(disp->remoteauthdata); sfree(disp->remoteauthprotoname); sfree(disp->remoteauthdatastring); @@ -487,7 +487,7 @@ void x11_get_auth_from_authfile(struct X11Display *disp, done: fclose(authfp); - memset(buf, 0, 65537 * 4); + smemclr(buf, 65537 * 4); sfree(buf); sfree(ourhostname); }