diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-24 15:33:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-24 15:33:32 -0400 |
commit | 14d4cc08832efb724e58944ba2ac22e2ca3143dc (patch) | |
tree | febca1365a5306d5a44b2481ec41f13f4c2defc2 | |
parent | 1c45d9a920e6ef4fce38921e4fc776c2abca3197 (diff) | |
parent | 7185ad2672a7d50bc384de0e38d90b75d99f3d82 (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.c | 3 | ||||
-rw-r--r-- | crypto/sha1_generic.c | 2 | ||||
-rw-r--r-- | crypto/sha256_generic.c | 5 | ||||
-rw-r--r-- | crypto/sha512_generic.c | 2 | ||||
-rw-r--r-- | crypto/tgr192.c | 4 | ||||
-rw-r--r-- | crypto/vmac.c | 2 | ||||
-rw-r--r-- | crypto/wp512.c | 8 | ||||
-rw-r--r-- | drivers/char/random.c | 8 | ||||
-rw-r--r-- | include/linux/string.h | 5 | ||||
-rw-r--r-- | lib/string.c | 16 |
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 | |||
218 | static int sha224_init(struct shash_desc *desc) | 217 | static 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 | ||
134 | extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, | 134 | extern 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 | ||
147 | extern size_t memweight(const void *ptr, size_t bytes); | 147 | size_t memweight(const void *ptr, size_t bytes); |
148 | void 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) | |||
598 | EXPORT_SYMBOL(memset); | 598 | EXPORT_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 | */ | ||
610 | void memzero_explicit(void *s, size_t count) | ||
611 | { | ||
612 | memset(s, 0, count); | ||
613 | OPTIMIZER_HIDE_VAR(s); | ||
614 | } | ||
615 | EXPORT_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 |