aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-24 15:33:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-24 15:33:32 -0400
commit14d4cc08832efb724e58944ba2ac22e2ca3143dc (patch)
treefebca1365a5306d5a44b2481ec41f13f4c2defc2
parent1c45d9a920e6ef4fce38921e4fc776c2abca3197 (diff)
parent7185ad2672a7d50bc384de0e38d90b75d99f3d82 (diff)
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
-rw-r--r--crypto/cts.c3
-rw-r--r--crypto/sha1_generic.c2
-rw-r--r--crypto/sha256_generic.c5
-rw-r--r--crypto/sha512_generic.c2
-rw-r--r--crypto/tgr192.c4
-rw-r--r--crypto/vmac.c2
-rw-r--r--crypto/wp512.c8
-rw-r--r--drivers/char/random.c8
-rw-r--r--include/linux/string.h5
-rw-r--r--lib/string.c16
10 files changed, 36 insertions, 19 deletions
diff --git a/crypto/cts.c b/crypto/cts.c
index 042223f8e733..133f0874c95e 100644
--- a/crypto/cts.c
+++ b/crypto/cts.c
@@ -202,7 +202,8 @@ static int cts_cbc_decrypt(struct crypto_cts_ctx *ctx,
202 /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */ 202 /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */
203 memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn); 203 memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn);
204 /* 6. Decrypt En to create Pn-1 */ 204 /* 6. Decrypt En to create Pn-1 */
205 memset(iv, 0, sizeof(iv)); 205 memzero_explicit(iv, sizeof(iv));
206
206 sg_set_buf(&sgsrc[0], s + bsize, bsize); 207 sg_set_buf(&sgsrc[0], s + bsize, bsize);
207 sg_set_buf(&sgdst[0], d, bsize); 208 sg_set_buf(&sgdst[0], d, bsize);
208 err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); 209 err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize);
diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c
index 42794803c480..7bb047432782 100644
--- a/crypto/sha1_generic.c
+++ b/crypto/sha1_generic.c
@@ -64,7 +64,7 @@ int crypto_sha1_update(struct shash_desc *desc, const u8 *data,
64 src = data + done; 64 src = data + done;
65 } while (done + SHA1_BLOCK_SIZE <= len); 65 } while (done + SHA1_BLOCK_SIZE <= len);
66 66
67 memset(temp, 0, sizeof(temp)); 67 memzero_explicit(temp, sizeof(temp));
68 partial = 0; 68 partial = 0;
69 } 69 }
70 memcpy(sctx->buffer + partial, src, len - done); 70 memcpy(sctx->buffer + partial, src, len - done);
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
index 0bb558344699..65e7b76b057f 100644
--- a/crypto/sha256_generic.c
+++ b/crypto/sha256_generic.c
@@ -211,10 +211,9 @@ static void sha256_transform(u32 *state, const u8 *input)
211 211
212 /* clear any sensitive info... */ 212 /* clear any sensitive info... */
213 a = b = c = d = e = f = g = h = t1 = t2 = 0; 213 a = b = c = d = e = f = g = h = t1 = t2 = 0;
214 memset(W, 0, 64 * sizeof(u32)); 214 memzero_explicit(W, 64 * sizeof(u32));
215} 215}
216 216
217
218static int sha224_init(struct shash_desc *desc) 217static int sha224_init(struct shash_desc *desc)
219{ 218{
220 struct sha256_state *sctx = shash_desc_ctx(desc); 219 struct sha256_state *sctx = shash_desc_ctx(desc);
@@ -317,7 +316,7 @@ static int sha224_final(struct shash_desc *desc, u8 *hash)
317 sha256_final(desc, D); 316 sha256_final(desc, D);
318 317
319 memcpy(hash, D, SHA224_DIGEST_SIZE); 318 memcpy(hash, D, SHA224_DIGEST_SIZE);
320 memset(D, 0, SHA256_DIGEST_SIZE); 319 memzero_explicit(D, SHA256_DIGEST_SIZE);
321 320
322 return 0; 321 return 0;
323} 322}
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index 6dde57dc511b..95db67197cd9 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -239,7 +239,7 @@ static int sha384_final(struct shash_desc *desc, u8 *hash)
239 sha512_final(desc, D); 239 sha512_final(desc, D);
240 240
241 memcpy(hash, D, 48); 241 memcpy(hash, D, 48);
242 memset(D, 0, 64); 242 memzero_explicit(D, 64);
243 243
244 return 0; 244 return 0;
245} 245}
diff --git a/crypto/tgr192.c b/crypto/tgr192.c
index 87403556fd0b..3c7af0d1ff7a 100644
--- a/crypto/tgr192.c
+++ b/crypto/tgr192.c
@@ -612,7 +612,7 @@ static int tgr160_final(struct shash_desc *desc, u8 * out)
612 612
613 tgr192_final(desc, D); 613 tgr192_final(desc, D);
614 memcpy(out, D, TGR160_DIGEST_SIZE); 614 memcpy(out, D, TGR160_DIGEST_SIZE);
615 memset(D, 0, TGR192_DIGEST_SIZE); 615 memzero_explicit(D, TGR192_DIGEST_SIZE);
616 616
617 return 0; 617 return 0;
618} 618}
@@ -623,7 +623,7 @@ static int tgr128_final(struct shash_desc *desc, u8 * out)
623 623
624 tgr192_final(desc, D); 624 tgr192_final(desc, D);
625 memcpy(out, D, TGR128_DIGEST_SIZE); 625 memcpy(out, D, TGR128_DIGEST_SIZE);
626 memset(D, 0, TGR192_DIGEST_SIZE); 626 memzero_explicit(D, TGR192_DIGEST_SIZE);
627 627
628 return 0; 628 return 0;
629} 629}
diff --git a/crypto/vmac.c b/crypto/vmac.c
index 2eb11a30c29c..d84c24bd7ff7 100644
--- a/crypto/vmac.c
+++ b/crypto/vmac.c
@@ -613,7 +613,7 @@ static int vmac_final(struct shash_desc *pdesc, u8 *out)
613 } 613 }
614 mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx); 614 mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx);
615 memcpy(out, &mac, sizeof(vmac_t)); 615 memcpy(out, &mac, sizeof(vmac_t));
616 memset(&mac, 0, sizeof(vmac_t)); 616 memzero_explicit(&mac, sizeof(vmac_t));
617 memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx)); 617 memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx));
618 ctx->partial_size = 0; 618 ctx->partial_size = 0;
619 return 0; 619 return 0;
diff --git a/crypto/wp512.c b/crypto/wp512.c
index 180f1d6e03f4..ec64e7762fbb 100644
--- a/crypto/wp512.c
+++ b/crypto/wp512.c
@@ -1102,8 +1102,8 @@ static int wp384_final(struct shash_desc *desc, u8 *out)
1102 u8 D[64]; 1102 u8 D[64];
1103 1103
1104 wp512_final(desc, D); 1104 wp512_final(desc, D);
1105 memcpy (out, D, WP384_DIGEST_SIZE); 1105 memcpy(out, D, WP384_DIGEST_SIZE);
1106 memset (D, 0, WP512_DIGEST_SIZE); 1106 memzero_explicit(D, WP512_DIGEST_SIZE);
1107 1107
1108 return 0; 1108 return 0;
1109} 1109}
@@ -1113,8 +1113,8 @@ static int wp256_final(struct shash_desc *desc, u8 *out)
1113 u8 D[64]; 1113 u8 D[64];
1114 1114
1115 wp512_final(desc, D); 1115 wp512_final(desc, D);
1116 memcpy (out, D, WP256_DIGEST_SIZE); 1116 memcpy(out, D, WP256_DIGEST_SIZE);
1117 memset (D, 0, WP512_DIGEST_SIZE); 1117 memzero_explicit(D, WP512_DIGEST_SIZE);
1118 1118
1119 return 0; 1119 return 0;
1120} 1120}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 82759cef9043..04645c09fe5e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1106,7 +1106,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
1106 __mix_pool_bytes(r, hash.w, sizeof(hash.w)); 1106 __mix_pool_bytes(r, hash.w, sizeof(hash.w));
1107 spin_unlock_irqrestore(&r->lock, flags); 1107 spin_unlock_irqrestore(&r->lock, flags);
1108 1108
1109 memset(workspace, 0, sizeof(workspace)); 1109 memzero_explicit(workspace, sizeof(workspace));
1110 1110
1111 /* 1111 /*
1112 * In case the hash function has some recognizable output 1112 * In case the hash function has some recognizable output
@@ -1118,7 +1118,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
1118 hash.w[2] ^= rol32(hash.w[2], 16); 1118 hash.w[2] ^= rol32(hash.w[2], 16);
1119 1119
1120 memcpy(out, &hash, EXTRACT_SIZE); 1120 memcpy(out, &hash, EXTRACT_SIZE);
1121 memset(&hash, 0, sizeof(hash)); 1121 memzero_explicit(&hash, sizeof(hash));
1122} 1122}
1123 1123
1124/* 1124/*
@@ -1175,7 +1175,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
1175 } 1175 }
1176 1176
1177 /* Wipe data just returned from memory */ 1177 /* Wipe data just returned from memory */
1178 memset(tmp, 0, sizeof(tmp)); 1178 memzero_explicit(tmp, sizeof(tmp));
1179 1179
1180 return ret; 1180 return ret;
1181} 1181}
@@ -1218,7 +1218,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
1218 } 1218 }
1219 1219
1220 /* Wipe data just returned from memory */ 1220 /* Wipe data just returned from memory */
1221 memset(tmp, 0, sizeof(tmp)); 1221 memzero_explicit(tmp, sizeof(tmp));
1222 1222
1223 return ret; 1223 return ret;
1224} 1224}
diff --git a/include/linux/string.h b/include/linux/string.h
index e6edfe51575a..2e22a2e58f3a 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -132,7 +132,7 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
132#endif 132#endif
133 133
134extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, 134extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
135 const void *from, size_t available); 135 const void *from, size_t available);
136 136
137/** 137/**
138 * strstarts - does @str start with @prefix? 138 * strstarts - does @str start with @prefix?
@@ -144,7 +144,8 @@ static inline bool strstarts(const char *str, const char *prefix)
144 return strncmp(str, prefix, strlen(prefix)) == 0; 144 return strncmp(str, prefix, strlen(prefix)) == 0;
145} 145}
146 146
147extern size_t memweight(const void *ptr, size_t bytes); 147size_t memweight(const void *ptr, size_t bytes);
148void memzero_explicit(void *s, size_t count);
148 149
149/** 150/**
150 * kbasename - return the last part of a pathname. 151 * kbasename - return the last part of a pathname.
diff --git a/lib/string.c b/lib/string.c
index 2fc20aa06f84..10063300b830 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -598,6 +598,22 @@ void *memset(void *s, int c, size_t count)
598EXPORT_SYMBOL(memset); 598EXPORT_SYMBOL(memset);
599#endif 599#endif
600 600
601/**
602 * memzero_explicit - Fill a region of memory (e.g. sensitive
603 * keying data) with 0s.
604 * @s: Pointer to the start of the area.
605 * @count: The size of the area.
606 *
607 * memzero_explicit() doesn't need an arch-specific version as
608 * it just invokes the one of memset() implicitly.
609 */
610void memzero_explicit(void *s, size_t count)
611{
612 memset(s, 0, count);
613 OPTIMIZER_HIDE_VAR(s);
614}
615EXPORT_SYMBOL(memzero_explicit);
616
601#ifndef __HAVE_ARCH_MEMCPY 617#ifndef __HAVE_ARCH_MEMCPY
602/** 618/**
603 * memcpy - Copy one area of memory to another 619 * memcpy - Copy one area of memory to another