]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Introduce a new utility function smemclr(), which memsets things to
authorSimon Tatham <anakin@pobox.com>
Sun, 22 Jul 2012 19:51:50 +0000 (19:51 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 22 Jul 2012 19:51:50 +0000 (19:51 +0000)
zero but does it in such a way that over-clever compilers hopefully
won't helpfully optimise the call away if you do it just before
freeing something or letting it go out of scope. Use this for
(hopefully) every memset whose job is to destroy sensitive data that
might otherwise be left lying around in the process's memory.

[originally from svn r9586]

21 files changed:
cmdgen.c
cmdline.c
import.c
misc.c
putty.h
ssh.c
sshaes.c
ssharcf.c
sshbn.c
sshdes.c
sshdss.c
sshmd5.c
sshpubk.c
sshrsa.c
sshsha.c
unix/gtkwin.c
windows/winmisc.c
windows/winpgen.c
windows/winpgnt.c
windows/winstuff.h
x11fwd.c

index 50f99f70183f41c884b4cdcd185bf0e11adf5b32..5b0e54d9afec3f849a6e4259c7c871f3f3d1fe2c 100644 (file)
--- 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);
     }
 
index 2c3b7ce5caf0715ea62c4ba213999d90b2d0e11b..a4c91601079e1b461007fe22a03edf08dfcaa3d5 100644 (file)
--- 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));
        }
     }
 
index 55e3be27bed76a4af24f160a141bffbeae55b4b2..05cfdc147478f25f8cac5f455821ca5ced1d202e 100644 (file)
--- 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 636ca9f39f003a60901ea4f2495c0cdf027775af..76e5fab2104cce621f8895dc49943b8ec2008a2e 100644 (file)
--- 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 dcc80db57717549da03b866fd12956fc6908d50a..b32b0fa1e51ee885195513a01ed215240aa79ad8 100644 (file)
--- 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 ef503bf52160e96503828ad72bbd5d67c377031e..1f1a26567434f65a12d054e3cba2caf682ec024a 100644 (file)
--- 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 {
index 2800e021f0d0d1ed66733c8cadbabadf2a0d0fde..97935b7f19ee4c8f59f5cbd1df5e665083014973 100644 (file)
--- 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 = {
index 6bfbd8959531ee63a5524b22542454aba0d8a8e0..06f235c5be069ab7d70aaedc1be7f4d910088ed4 100644 (file)
--- 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 484c423f022490b030e797afbee2cd5e9f0b0372..999817db4714a3271d942b4bb97e6832c894c205 100644 (file)
--- 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);
 }
 
index b12a91d5169d879d32c4832f1ed53b31c4ae00a9..03d2b3ae46baa73e6c73d3dc5543123cf995870a 100644 (file)
--- 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)
index 7c95d11b65c5ecf975d2773d89793fcd8c23b5bc..6cf5830d5bc64994b2ab6ec0aae3d0118834a5b5 100644 (file)
--- 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.
index 7112d406065ac7299bb028e322a4dcdc720c3426..e5187a661662b4b793330055f717222b503a0572 100644 (file)
--- 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)
index 88ff17921dcb97978a0b04dfb4ad163567e827c2..c29d8a58ad4a2bd55bcdcaccfc146195027725f4 100644 (file)
--- 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;
index 0c1b2ef5a421d642a5fd57e26e26ad02a1902216..77a6bb250cec41c11b2e4df6ccac28aef1c7ab5a 100644 (file)
--- 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));
 }
 
 /*
index cbe9d78b43b1d1694a130375dc60bf124e12a5ac..30113511b44527819c5c4d6a858c8b53bef823e7 100644 (file)
--- 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)
index 03f2855159ff7c19afd05fff01b292ebd05d967b..241aa6bcdd9b159857594a7a64182fe99d08f3e3 100644 (file)
@@ -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
index f54e8a4d6e0d2ebea272a6eeea7723e39bc28f33..2166f4530ab6d9abb970580a48e6c22c15872a9b 100644 (file)
@@ -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;
index c83d0d20cd5ce04dd96fa6a15c1325999196d775..ffbeb1a4ee0784cea95e4050b90c4428ce63adcf 100644 (file)
@@ -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;
 
index 291593e49e4495a836a50e830e39642223c550a3..21a69cc003a3a687898af4b9b8fad79fb9869f22 100644 (file)
@@ -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 ... */
index df59631c404a59b3d07fcf7838f91fa28d2d8a1e..d81515dc7071615ca9ac4a1c020e6044a2b902da 100644 (file)
@@ -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:
  *
index 5b4f76cdcb0e95c0899b9e088dc4eff1dcd2c668..1e04f542b83dd867761fd260fbd4b2fd851c0068 100644 (file)
--- 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);
 }