This adds a memzero_explicit() call which is guaranteed not to be

optimized away by GCC.  This is important when we are wiping
 cryptographically sensitive material.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJUQTmuAAoJENNvdpvBGATwFToP/jOGL/Z5NE7Oa33jC+oRDdEC
 6gDXi27emzkll5BsxRLOR26vxXZ9AsBBI+U9pmhy64pcSUSxocTIZ+Bh0bx/LQyd
 w6HTTTYFk9GNtQCGrxRoNBPLdH/qz83ClvlWmpjsYpIEFfSOU3YncygSbps3uSeZ
 tdXiI5G1zZNGrljQrL+roJCZX5TP4XxHFbdUjeyV9Z8210oYTwCfpzHjg9+D24f0
 rwTOHa0Lp6IrecU4Vlq4PFP+y4/ZdYYVwnpyX5UtTHP3QP176PcrwvnAl4Ys/8Lx
 9uqj+gNrUnC6KHsSKhUxwMq9Ch7nu6iLLAYuIUMvxZargsmbNQFShHZyu2mwDgko
 bp+oTw8byOQyv6g/hbFpTVwfwpiv/AGu8VxmG3ORGqndOldTh+oQ9xMnuBZA8sXX
 PxHxEUY9hr66nVFg4iuxT/2KJJA+Ol8ARkB0taCWhwavzxXJeedEVEw5nbtQxRsM
 AJGxjBsAgSw7SJD03yAQH5kRGYvIdv03JRbIiMPmKjlP+pl1JkzOAPhVMUD+24vI
 x6oFpSa5FH5utlt3nCZuxlOYBuWhWKIhUzEoY2HwCsyISQScPcwL9EP15sWceY5i
 8+Wylvf+yqGVU3KopCBBV/oX3Wm/kj1A8OP/4Kk8UHw9k2btjYETYayhP1DHKnIt
 /4pr4+oGd5GlFOHRteXp
 =i29U
 -----END PGP SIGNATURE-----

Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random

Pull /dev/random updates from Ted Ts'o:
 "This adds a memzero_explicit() call which is guaranteed not to be
  optimized away by GCC.  This is important when we are wiping
  cryptographically sensitive material"

* tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
  crypto: memzero_explicit - make sure to clear out sensitive data
  random: add and use memzero_explicit() for clearing data
This commit is contained in:
Linus Torvalds 2014-10-24 12:33:32 -07:00
commit 14d4cc0883
10 changed files with 36 additions and 19 deletions

View file

@ -202,7 +202,8 @@ static int cts_cbc_decrypt(struct crypto_cts_ctx *ctx,
/* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */ /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */
memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn); memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn);
/* 6. Decrypt En to create Pn-1 */ /* 6. Decrypt En to create Pn-1 */
memset(iv, 0, sizeof(iv)); memzero_explicit(iv, sizeof(iv));
sg_set_buf(&sgsrc[0], s + bsize, bsize); sg_set_buf(&sgsrc[0], s + bsize, bsize);
sg_set_buf(&sgdst[0], d, bsize); sg_set_buf(&sgdst[0], d, bsize);
err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize);

View file

@ -64,7 +64,7 @@ int crypto_sha1_update(struct shash_desc *desc, const u8 *data,
src = data + done; src = data + done;
} while (done + SHA1_BLOCK_SIZE <= len); } while (done + SHA1_BLOCK_SIZE <= len);
memset(temp, 0, sizeof(temp)); memzero_explicit(temp, sizeof(temp));
partial = 0; partial = 0;
} }
memcpy(sctx->buffer + partial, src, len - done); memcpy(sctx->buffer + partial, src, len - done);

View file

@ -211,10 +211,9 @@ static void sha256_transform(u32 *state, const u8 *input)
/* clear any sensitive info... */ /* clear any sensitive info... */
a = b = c = d = e = f = g = h = t1 = t2 = 0; a = b = c = d = e = f = g = h = t1 = t2 = 0;
memset(W, 0, 64 * sizeof(u32)); memzero_explicit(W, 64 * sizeof(u32));
} }
static int sha224_init(struct shash_desc *desc) static int sha224_init(struct shash_desc *desc)
{ {
struct sha256_state *sctx = shash_desc_ctx(desc); struct sha256_state *sctx = shash_desc_ctx(desc);
@ -317,7 +316,7 @@ static int sha224_final(struct shash_desc *desc, u8 *hash)
sha256_final(desc, D); sha256_final(desc, D);
memcpy(hash, D, SHA224_DIGEST_SIZE); memcpy(hash, D, SHA224_DIGEST_SIZE);
memset(D, 0, SHA256_DIGEST_SIZE); memzero_explicit(D, SHA256_DIGEST_SIZE);
return 0; return 0;
} }

View file

@ -239,7 +239,7 @@ static int sha384_final(struct shash_desc *desc, u8 *hash)
sha512_final(desc, D); sha512_final(desc, D);
memcpy(hash, D, 48); memcpy(hash, D, 48);
memset(D, 0, 64); memzero_explicit(D, 64);
return 0; return 0;
} }

View file

@ -612,7 +612,7 @@ static int tgr160_final(struct shash_desc *desc, u8 * out)
tgr192_final(desc, D); tgr192_final(desc, D);
memcpy(out, D, TGR160_DIGEST_SIZE); memcpy(out, D, TGR160_DIGEST_SIZE);
memset(D, 0, TGR192_DIGEST_SIZE); memzero_explicit(D, TGR192_DIGEST_SIZE);
return 0; return 0;
} }
@ -623,7 +623,7 @@ static int tgr128_final(struct shash_desc *desc, u8 * out)
tgr192_final(desc, D); tgr192_final(desc, D);
memcpy(out, D, TGR128_DIGEST_SIZE); memcpy(out, D, TGR128_DIGEST_SIZE);
memset(D, 0, TGR192_DIGEST_SIZE); memzero_explicit(D, TGR192_DIGEST_SIZE);
return 0; return 0;
} }

View file

@ -613,7 +613,7 @@ static int vmac_final(struct shash_desc *pdesc, u8 *out)
} }
mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx); mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx);
memcpy(out, &mac, sizeof(vmac_t)); memcpy(out, &mac, sizeof(vmac_t));
memset(&mac, 0, sizeof(vmac_t)); memzero_explicit(&mac, sizeof(vmac_t));
memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx)); memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx));
ctx->partial_size = 0; ctx->partial_size = 0;
return 0; return 0;

View file

@ -1102,8 +1102,8 @@ static int wp384_final(struct shash_desc *desc, u8 *out)
u8 D[64]; u8 D[64];
wp512_final(desc, D); wp512_final(desc, D);
memcpy (out, D, WP384_DIGEST_SIZE); memcpy(out, D, WP384_DIGEST_SIZE);
memset (D, 0, WP512_DIGEST_SIZE); memzero_explicit(D, WP512_DIGEST_SIZE);
return 0; return 0;
} }
@ -1113,8 +1113,8 @@ static int wp256_final(struct shash_desc *desc, u8 *out)
u8 D[64]; u8 D[64];
wp512_final(desc, D); wp512_final(desc, D);
memcpy (out, D, WP256_DIGEST_SIZE); memcpy(out, D, WP256_DIGEST_SIZE);
memset (D, 0, WP512_DIGEST_SIZE); memzero_explicit(D, WP512_DIGEST_SIZE);
return 0; return 0;
} }

View file

@ -1106,7 +1106,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
__mix_pool_bytes(r, hash.w, sizeof(hash.w)); __mix_pool_bytes(r, hash.w, sizeof(hash.w));
spin_unlock_irqrestore(&r->lock, flags); spin_unlock_irqrestore(&r->lock, flags);
memset(workspace, 0, sizeof(workspace)); memzero_explicit(workspace, sizeof(workspace));
/* /*
* In case the hash function has some recognizable output * In case the hash function has some recognizable output
@ -1118,7 +1118,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
hash.w[2] ^= rol32(hash.w[2], 16); hash.w[2] ^= rol32(hash.w[2], 16);
memcpy(out, &hash, EXTRACT_SIZE); memcpy(out, &hash, EXTRACT_SIZE);
memset(&hash, 0, sizeof(hash)); memzero_explicit(&hash, sizeof(hash));
} }
/* /*
@ -1175,7 +1175,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
} }
/* Wipe data just returned from memory */ /* Wipe data just returned from memory */
memset(tmp, 0, sizeof(tmp)); memzero_explicit(tmp, sizeof(tmp));
return ret; return ret;
} }
@ -1218,7 +1218,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
} }
/* Wipe data just returned from memory */ /* Wipe data just returned from memory */
memset(tmp, 0, sizeof(tmp)); memzero_explicit(tmp, sizeof(tmp));
return ret; return ret;
} }

View file

@ -132,7 +132,7 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
#endif #endif
extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
const void *from, size_t available); const void *from, size_t available);
/** /**
* strstarts - does @str start with @prefix? * strstarts - does @str start with @prefix?
@ -144,7 +144,8 @@ static inline bool strstarts(const char *str, const char *prefix)
return strncmp(str, prefix, strlen(prefix)) == 0; return strncmp(str, prefix, strlen(prefix)) == 0;
} }
extern size_t memweight(const void *ptr, size_t bytes); size_t memweight(const void *ptr, size_t bytes);
void memzero_explicit(void *s, size_t count);
/** /**
* kbasename - return the last part of a pathname. * kbasename - return the last part of a pathname.

View file

@ -598,6 +598,22 @@ void *memset(void *s, int c, size_t count)
EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memset);
#endif #endif
/**
* memzero_explicit - Fill a region of memory (e.g. sensitive
* keying data) with 0s.
* @s: Pointer to the start of the area.
* @count: The size of the area.
*
* memzero_explicit() doesn't need an arch-specific version as
* it just invokes the one of memset() implicitly.
*/
void memzero_explicit(void *s, size_t count)
{
memset(s, 0, count);
OPTIMIZER_HIDE_VAR(s);
}
EXPORT_SYMBOL(memzero_explicit);
#ifndef __HAVE_ARCH_MEMCPY #ifndef __HAVE_ARCH_MEMCPY
/** /**
* memcpy - Copy one area of memory to another * memcpy - Copy one area of memory to another