Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: padlock - fix VIA PadLock instruction usage with irq_ts_save/restore()
  crypto: hash - Add missing top-level functions
  crypto: hash - Fix digest size check for digest type
  crypto: tcrypt - Fix AEAD chunk testing
  crypto: talitos - Add handling for SEC 3.x treatment of link table
  • Loading branch information
Linus Torvalds committed Aug 13, 2008
2 parents 9ea319b + e491401 commit 8d0968a
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 26 deletions.
2 changes: 1 addition & 1 deletion crypto/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ int crypto_init_digest_ops_async(struct crypto_tfm *tfm)
struct ahash_tfm *crt = &tfm->crt_ahash;
struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;

if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm))
if (dalg->dia_digestsize > PAGE_SIZE / 8)
return -EINVAL;

crt->init = digest_async_init;
Expand Down
28 changes: 19 additions & 9 deletions crypto/tcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,21 +481,31 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,

for (k = 0, temp = 0; k < template[i].np; k++) {
printk(KERN_INFO "page %u\n", k);
q = &axbuf[IDX[k]];
hexdump(q, template[i].tap[k]);
q = &xbuf[IDX[k]];

n = template[i].tap[k];
if (k == template[i].np - 1)
n += enc ? authsize : -authsize;
hexdump(q, n);
printk(KERN_INFO "%s\n",
memcmp(q, template[i].result + temp,
template[i].tap[k] -
(k < template[i].np - 1 || enc ?
0 : authsize)) ?
memcmp(q, template[i].result + temp, n) ?
"fail" : "pass");

for (n = 0; q[template[i].tap[k] + n]; n++)
;
q += n;
if (k == template[i].np - 1 && !enc) {
if (memcmp(q, template[i].input +
temp + n, authsize))
n = authsize;
else
n = 0;
} else {
for (n = 0; q[n]; n++)
;
}
if (n) {
printk("Result buffer corruption %u "
"bytes:\n", n);
hexdump(&q[template[i].tap[k]], n);
hexdump(q, n);
}

temp += template[i].tap[k];
Expand Down
8 changes: 8 additions & 0 deletions drivers/char/hw_random/via-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <asm/io.h>
#include <asm/msr.h>
#include <asm/cpufeature.h>
#include <asm/i387.h>


#define PFX KBUILD_MODNAME ": "
Expand Down Expand Up @@ -67,16 +68,23 @@ enum {
* Another possible performance boost may come from simply buffering
* until we have 4 bytes, thus returning a u32 at a time,
* instead of the current u8-at-a-time.
*
* Padlock instructions can generate a spurious DNA fault, so
* we have to call them in the context of irq_ts_save/restore()
*/

static inline u32 xstore(u32 *addr, u32 edx_in)
{
u32 eax_out;
int ts_state;

ts_state = irq_ts_save();

asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
:"=m"(*addr), "=a"(eax_out)
:"D"(addr), "d"(edx_in));

irq_ts_restore(ts_state);
return eax_out;
}

Expand Down
28 changes: 27 additions & 1 deletion drivers/crypto/padlock-aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <asm/byteorder.h>
#include <asm/i387.h>
#include "padlock.h"

/* Control word. */
Expand Down Expand Up @@ -141,6 +142,12 @@ static inline void padlock_reset_key(void)
asm volatile ("pushfl; popfl");
}

/*
* While the padlock instructions don't use FP/SSE registers, they
* generate a spurious DNA fault when cr0.ts is '1'. These instructions
* should be used only inside the irq_ts_save/restore() context
*/

static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
void *control_word)
{
Expand Down Expand Up @@ -205,15 +212,23 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct aes_ctx *ctx = aes_ctx(tfm);
int ts_state;
padlock_reset_key();

ts_state = irq_ts_save();
aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
irq_ts_restore(ts_state);
}

static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct aes_ctx *ctx = aes_ctx(tfm);
int ts_state;
padlock_reset_key();

ts_state = irq_ts_save();
aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
irq_ts_restore(ts_state);
}

static struct crypto_alg aes_alg = {
Expand Down Expand Up @@ -244,19 +259,22 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
struct blkcipher_walk walk;
int err;
int ts_state;

padlock_reset_key();

blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);

ts_state = irq_ts_save();
while ((nbytes = walk.nbytes)) {
padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
ctx->E, &ctx->cword.encrypt,
nbytes / AES_BLOCK_SIZE);
nbytes &= AES_BLOCK_SIZE - 1;
err = blkcipher_walk_done(desc, &walk, nbytes);
}
irq_ts_restore(ts_state);

return err;
}
Expand All @@ -268,20 +286,22 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
struct blkcipher_walk walk;
int err;
int ts_state;

padlock_reset_key();

blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);

ts_state = irq_ts_save();
while ((nbytes = walk.nbytes)) {
padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
ctx->D, &ctx->cword.decrypt,
nbytes / AES_BLOCK_SIZE);
nbytes &= AES_BLOCK_SIZE - 1;
err = blkcipher_walk_done(desc, &walk, nbytes);
}

irq_ts_restore(ts_state);
return err;
}

Expand Down Expand Up @@ -314,12 +334,14 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
struct blkcipher_walk walk;
int err;
int ts_state;

padlock_reset_key();

blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);

ts_state = irq_ts_save();
while ((nbytes = walk.nbytes)) {
u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr,
walk.dst.virt.addr, ctx->E,
Expand All @@ -329,6 +351,7 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
nbytes &= AES_BLOCK_SIZE - 1;
err = blkcipher_walk_done(desc, &walk, nbytes);
}
irq_ts_restore(ts_state);

return err;
}
Expand All @@ -340,12 +363,14 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
struct blkcipher_walk walk;
int err;
int ts_state;

padlock_reset_key();

blkcipher_walk_init(&walk, dst, src, nbytes);
err = blkcipher_walk_virt(desc, &walk);

ts_state = irq_ts_save();
while ((nbytes = walk.nbytes)) {
padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr,
ctx->D, walk.iv, &ctx->cword.decrypt,
Expand All @@ -354,6 +379,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
err = blkcipher_walk_done(desc, &walk, nbytes);
}

irq_ts_restore(ts_state);
return err;
}

Expand Down
9 changes: 9 additions & 0 deletions drivers/crypto/padlock-sha.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/scatterlist.h>
#include <asm/i387.h>
#include "padlock.h"

#define SHA1_DEFAULT_FALLBACK "sha1-generic"
Expand Down Expand Up @@ -102,16 +103,20 @@ static void padlock_do_sha1(const char *in, char *out, int count)
* PadLock microcode needs it that big. */
char buf[128+16];
char *result = NEAREST_ALIGNED(buf);
int ts_state;

((uint32_t *)result)[0] = SHA1_H0;
((uint32_t *)result)[1] = SHA1_H1;
((uint32_t *)result)[2] = SHA1_H2;
((uint32_t *)result)[3] = SHA1_H3;
((uint32_t *)result)[4] = SHA1_H4;

/* prevent taking the spurious DNA fault with padlock. */
ts_state = irq_ts_save();
asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" /* rep xsha1 */
: "+S"(in), "+D"(result)
: "c"(count), "a"(0));
irq_ts_restore(ts_state);

padlock_output_block((uint32_t *)result, (uint32_t *)out, 5);
}
Expand All @@ -123,6 +128,7 @@ static void padlock_do_sha256(const char *in, char *out, int count)
* PadLock microcode needs it that big. */
char buf[128+16];
char *result = NEAREST_ALIGNED(buf);
int ts_state;

((uint32_t *)result)[0] = SHA256_H0;
((uint32_t *)result)[1] = SHA256_H1;
Expand All @@ -133,9 +139,12 @@ static void padlock_do_sha256(const char *in, char *out, int count)
((uint32_t *)result)[6] = SHA256_H6;
((uint32_t *)result)[7] = SHA256_H7;

/* prevent taking the spurious DNA fault with padlock. */
ts_state = irq_ts_save();
asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" /* rep xsha256 */
: "+S"(in), "+D"(result)
: "c"(count), "a"(0));
irq_ts_restore(ts_state);

padlock_output_block((uint32_t *)result, (uint32_t *)out, 8);
}
Expand Down
Loading

0 comments on commit 8d0968a

Please sign in to comment.