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:
commit
14d4cc0883
10 changed files with 36 additions and 19 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
16
lib/string.c
16
lib/string.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue