Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 4174
b: refs/heads/master
c: 6789b2d
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Jul 6, 2005
1 parent 4157c8e commit a9345b6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 95477377995aefa2ec1654a9a3777bd57ea99146
refs/heads/master: 6789b2dc455b90efc9c88886c9366adc9abb7347
102 changes: 41 additions & 61 deletions trunk/drivers/crypto/padlock-aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <linux/errno.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <asm/byteorder.h>
#include "padlock.h"

Expand All @@ -59,8 +60,12 @@
#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))

struct aes_ctx {
uint32_t e_data[AES_EXTENDED_KEY_SIZE+4];
uint32_t d_data[AES_EXTENDED_KEY_SIZE+4];
uint32_t e_data[AES_EXTENDED_KEY_SIZE];
uint32_t d_data[AES_EXTENDED_KEY_SIZE];
struct {
struct cword encrypt;
struct cword decrypt;
} cword;
uint32_t *E;
uint32_t *D;
int key_length;
Expand Down Expand Up @@ -280,10 +285,15 @@ aes_hw_extkey_available(uint8_t key_len)
return 0;
}

static inline struct aes_ctx *aes_ctx(void *ctx)
{
return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT);
}

static int
aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags)
{
struct aes_ctx *ctx = ctx_arg;
struct aes_ctx *ctx = aes_ctx(ctx_arg);
uint32_t i, t, u, v, w;
uint32_t P[AES_EXTENDED_KEY_SIZE];
uint32_t rounds;
Expand All @@ -295,25 +305,36 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t

ctx->key_length = key_len;

/*
* If the hardware is capable of generating the extended key
* itself we must supply the plain key for both encryption
* and decryption.
*/
ctx->E = ctx->e_data;
ctx->D = ctx->d_data;

/* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */
if ((int)(ctx->e_data) & 0x0F)
ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0]));

if ((int)(ctx->d_data) & 0x0F)
ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0]));
ctx->D = ctx->e_data;

E_KEY[0] = uint32_t_in (in_key);
E_KEY[1] = uint32_t_in (in_key + 4);
E_KEY[2] = uint32_t_in (in_key + 8);
E_KEY[3] = uint32_t_in (in_key + 12);

/* Prepare control words. */
memset(&ctx->cword, 0, sizeof(ctx->cword));

ctx->cword.decrypt.encdec = 1;
ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4;
ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds;
ctx->cword.encrypt.ksize = (key_len - 16) / 8;
ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize;

/* Don't generate extended keys if the hardware can do it. */
if (aes_hw_extkey_available(key_len))
return 0;

ctx->D = ctx->d_data;
ctx->cword.encrypt.keygen = 1;
ctx->cword.decrypt.keygen = 1;

switch (key_len) {
case 16:
t = E_KEY[3];
Expand Down Expand Up @@ -370,77 +391,36 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t
/* ====== Encryption/decryption routines ====== */

/* This is the real call to PadLock. */
static inline void
padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key,
void *control_word, uint32_t count)
static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
void *control_word, u32 count)
{
asm volatile ("pushfl; popfl"); /* enforce key reload. */
asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
: "+S"(input), "+D"(output)
: "d"(control_word), "b"(key), "c"(count));
}

static void
aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec)
{
/* Don't blindly modify this structure - the items must
fit on 16-Bytes boundaries! */
struct padlock_xcrypt_data {
uint8_t buf[AES_BLOCK_SIZE];
union cword cword;
};

struct aes_ctx *ctx = ctx_arg;
char bigbuf[sizeof(struct padlock_xcrypt_data) + 16];
struct padlock_xcrypt_data *data;
void *key;

/* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */
if (((long)bigbuf) & 0x0F)
data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F));
else
data = (void*)bigbuf;

/* Prepare Control word. */
memset (data, 0, sizeof(struct padlock_xcrypt_data));
data->cword.b.encdec = !encdec; /* in the rest of cryptoapi ENC=1/DEC=0 */
data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4;
data->cword.b.ksize = (ctx->key_length - 16) / 8;

/* Is the hardware capable to generate the extended key? */
if (!aes_hw_extkey_available(ctx->key_length))
data->cword.b.keygen = 1;

/* ctx->E starts with a plain key - if the hardware is capable
to generate the extended key itself we must supply
the plain key for both Encryption and Decryption. */
if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0)
key = ctx->E;
else
key = ctx->D;

memcpy(data->buf, in_arg, AES_BLOCK_SIZE);
padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1);
memcpy(out_arg, data->buf, AES_BLOCK_SIZE);
}

static void
aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
{
aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT);
struct aes_ctx *ctx = aes_ctx(ctx_arg);
padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1);
}

static void
aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
{
aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT);
struct aes_ctx *ctx = aes_ctx(ctx_arg);
padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1);
}

static struct crypto_alg aes_alg = {
.cra_name = "aes",
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct aes_ctx),
.cra_ctxsize = sizeof(struct aes_ctx) +
PADLOCK_ALIGNMENT,
.cra_alignmask = PADLOCK_ALIGNMENT - 1,
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
.cra_u = {
Expand Down
22 changes: 11 additions & 11 deletions trunk/drivers/crypto/padlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
#ifndef _CRYPTO_PADLOCK_H
#define _CRYPTO_PADLOCK_H

#define PADLOCK_ALIGNMENT 16

/* Control word. */
union cword {
uint32_t cword[4];
struct {
int rounds:4;
int algo:3;
int keygen:1;
int interm:1;
int encdec:1;
int ksize:2;
} b;
};
struct cword {
int __attribute__ ((__packed__))
rounds:4,
algo:3,
keygen:1,
interm:1,
encdec:1,
ksize:2;
} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));

#define PFX "padlock: "

Expand Down

0 comments on commit a9345b6

Please sign in to comment.