aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-07-06 20:04:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-06 20:04:06 -0400
commit359ea2f1352a77177540a213283bc7489f546ced (patch)
tree95a313a9d920e432bafcdf68a9c7fb0812aa389b /drivers
parent960b8466548c9bc6f718b5f470c1a58000fab09d (diff)
parente1d5dea1dfbfe484358c40db7f233ed6b5605646 (diff)
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/padlock-aes.c153
-rw-r--r--drivers/crypto/padlock.h22
2 files changed, 105 insertions, 70 deletions
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index ed708b4427b0..71407c578afe 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -49,6 +49,7 @@
49#include <linux/errno.h> 49#include <linux/errno.h>
50#include <linux/crypto.h> 50#include <linux/crypto.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/kernel.h>
52#include <asm/byteorder.h> 53#include <asm/byteorder.h>
53#include "padlock.h" 54#include "padlock.h"
54 55
@@ -59,8 +60,12 @@
59#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t)) 60#define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
60 61
61struct aes_ctx { 62struct aes_ctx {
62 uint32_t e_data[AES_EXTENDED_KEY_SIZE+4]; 63 uint32_t e_data[AES_EXTENDED_KEY_SIZE];
63 uint32_t d_data[AES_EXTENDED_KEY_SIZE+4]; 64 uint32_t d_data[AES_EXTENDED_KEY_SIZE];
65 struct {
66 struct cword encrypt;
67 struct cword decrypt;
68 } cword;
64 uint32_t *E; 69 uint32_t *E;
65 uint32_t *D; 70 uint32_t *D;
66 int key_length; 71 int key_length;
@@ -280,10 +285,15 @@ aes_hw_extkey_available(uint8_t key_len)
280 return 0; 285 return 0;
281} 286}
282 287
288static inline struct aes_ctx *aes_ctx(void *ctx)
289{
290 return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT);
291}
292
283static int 293static int
284aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags) 294aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags)
285{ 295{
286 struct aes_ctx *ctx = ctx_arg; 296 struct aes_ctx *ctx = aes_ctx(ctx_arg);
287 uint32_t i, t, u, v, w; 297 uint32_t i, t, u, v, w;
288 uint32_t P[AES_EXTENDED_KEY_SIZE]; 298 uint32_t P[AES_EXTENDED_KEY_SIZE];
289 uint32_t rounds; 299 uint32_t rounds;
@@ -295,25 +305,36 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t
295 305
296 ctx->key_length = key_len; 306 ctx->key_length = key_len;
297 307
308 /*
309 * If the hardware is capable of generating the extended key
310 * itself we must supply the plain key for both encryption
311 * and decryption.
312 */
298 ctx->E = ctx->e_data; 313 ctx->E = ctx->e_data;
299 ctx->D = ctx->d_data; 314 ctx->D = ctx->e_data;
300
301 /* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */
302 if ((int)(ctx->e_data) & 0x0F)
303 ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0]));
304
305 if ((int)(ctx->d_data) & 0x0F)
306 ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0]));
307 315
308 E_KEY[0] = uint32_t_in (in_key); 316 E_KEY[0] = uint32_t_in (in_key);
309 E_KEY[1] = uint32_t_in (in_key + 4); 317 E_KEY[1] = uint32_t_in (in_key + 4);
310 E_KEY[2] = uint32_t_in (in_key + 8); 318 E_KEY[2] = uint32_t_in (in_key + 8);
311 E_KEY[3] = uint32_t_in (in_key + 12); 319 E_KEY[3] = uint32_t_in (in_key + 12);
312 320
321 /* Prepare control words. */
322 memset(&ctx->cword, 0, sizeof(ctx->cword));
323
324 ctx->cword.decrypt.encdec = 1;
325 ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4;
326 ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds;
327 ctx->cword.encrypt.ksize = (key_len - 16) / 8;
328 ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize;
329
313 /* Don't generate extended keys if the hardware can do it. */ 330 /* Don't generate extended keys if the hardware can do it. */
314 if (aes_hw_extkey_available(key_len)) 331 if (aes_hw_extkey_available(key_len))
315 return 0; 332 return 0;
316 333
334 ctx->D = ctx->d_data;
335 ctx->cword.encrypt.keygen = 1;
336 ctx->cword.decrypt.keygen = 1;
337
317 switch (key_len) { 338 switch (key_len) {
318 case 16: 339 case 16:
319 t = E_KEY[3]; 340 t = E_KEY[3];
@@ -369,10 +390,9 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t
369 390
370/* ====== Encryption/decryption routines ====== */ 391/* ====== Encryption/decryption routines ====== */
371 392
372/* This is the real call to PadLock. */ 393/* These are the real call to PadLock. */
373static inline void 394static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
374padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key, 395 void *control_word, u32 count)
375 void *control_word, uint32_t count)
376{ 396{
377 asm volatile ("pushfl; popfl"); /* enforce key reload. */ 397 asm volatile ("pushfl; popfl"); /* enforce key reload. */
378 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ 398 asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
@@ -380,60 +400,70 @@ padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key,
380 : "d"(control_word), "b"(key), "c"(count)); 400 : "d"(control_word), "b"(key), "c"(count));
381} 401}
382 402
383static void 403static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
384aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec) 404 u8 *iv, void *control_word, u32 count)
385{ 405{
386 /* Don't blindly modify this structure - the items must 406 /* Enforce key reload. */
387 fit on 16-Bytes boundaries! */ 407 asm volatile ("pushfl; popfl");
388 struct padlock_xcrypt_data { 408 /* rep xcryptcbc */
389 uint8_t buf[AES_BLOCK_SIZE]; 409 asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
390 union cword cword; 410 : "+S" (input), "+D" (output), "+a" (iv)
391 }; 411 : "d" (control_word), "b" (key), "c" (count));
392 412 return iv;
393 struct aes_ctx *ctx = ctx_arg;
394 char bigbuf[sizeof(struct padlock_xcrypt_data) + 16];
395 struct padlock_xcrypt_data *data;
396 void *key;
397
398 /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */
399 if (((long)bigbuf) & 0x0F)
400 data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F));
401 else
402 data = (void*)bigbuf;
403
404 /* Prepare Control word. */
405 memset (data, 0, sizeof(struct padlock_xcrypt_data));
406 data->cword.b.encdec = !encdec; /* in the rest of cryptoapi ENC=1/DEC=0 */
407 data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4;
408 data->cword.b.ksize = (ctx->key_length - 16) / 8;
409
410 /* Is the hardware capable to generate the extended key? */
411 if (!aes_hw_extkey_available(ctx->key_length))
412 data->cword.b.keygen = 1;
413
414 /* ctx->E starts with a plain key - if the hardware is capable
415 to generate the extended key itself we must supply
416 the plain key for both Encryption and Decryption. */
417 if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0)
418 key = ctx->E;
419 else
420 key = ctx->D;
421
422 memcpy(data->buf, in_arg, AES_BLOCK_SIZE);
423 padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1);
424 memcpy(out_arg, data->buf, AES_BLOCK_SIZE);
425} 413}
426 414
427static void 415static void
428aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) 416aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
429{ 417{
430 aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT); 418 struct aes_ctx *ctx = aes_ctx(ctx_arg);
419 padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1);
431} 420}
432 421
433static void 422static void
434aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) 423aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
435{ 424{
436 aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT); 425 struct aes_ctx *ctx = aes_ctx(ctx_arg);
426 padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1);
427}
428
429static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
430 const u8 *in, unsigned int nbytes)
431{
432 struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
433 padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt,
434 nbytes / AES_BLOCK_SIZE);
435 return nbytes & ~(AES_BLOCK_SIZE - 1);
436}
437
438static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
439 const u8 *in, unsigned int nbytes)
440{
441 struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
442 padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt,
443 nbytes / AES_BLOCK_SIZE);
444 return nbytes & ~(AES_BLOCK_SIZE - 1);
445}
446
447static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
448 const u8 *in, unsigned int nbytes)
449{
450 struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
451 u8 *iv;
452
453 iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info,
454 &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE);
455 memcpy(desc->info, iv, AES_BLOCK_SIZE);
456
457 return nbytes & ~(AES_BLOCK_SIZE - 1);
458}
459
460static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
461 const u8 *in, unsigned int nbytes)
462{
463 struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
464 padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt,
465 nbytes / AES_BLOCK_SIZE);
466 return nbytes & ~(AES_BLOCK_SIZE - 1);
437} 467}
438 468
439static struct crypto_alg aes_alg = { 469static struct crypto_alg aes_alg = {
@@ -441,6 +471,7 @@ static struct crypto_alg aes_alg = {
441 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 471 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
442 .cra_blocksize = AES_BLOCK_SIZE, 472 .cra_blocksize = AES_BLOCK_SIZE,
443 .cra_ctxsize = sizeof(struct aes_ctx), 473 .cra_ctxsize = sizeof(struct aes_ctx),
474 .cra_alignmask = PADLOCK_ALIGNMENT - 1,
444 .cra_module = THIS_MODULE, 475 .cra_module = THIS_MODULE,
445 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 476 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
446 .cra_u = { 477 .cra_u = {
@@ -449,7 +480,11 @@ static struct crypto_alg aes_alg = {
449 .cia_max_keysize = AES_MAX_KEY_SIZE, 480 .cia_max_keysize = AES_MAX_KEY_SIZE,
450 .cia_setkey = aes_set_key, 481 .cia_setkey = aes_set_key,
451 .cia_encrypt = aes_encrypt, 482 .cia_encrypt = aes_encrypt,
452 .cia_decrypt = aes_decrypt 483 .cia_decrypt = aes_decrypt,
484 .cia_encrypt_ecb = aes_encrypt_ecb,
485 .cia_decrypt_ecb = aes_decrypt_ecb,
486 .cia_encrypt_cbc = aes_encrypt_cbc,
487 .cia_decrypt_cbc = aes_decrypt_cbc,
453 } 488 }
454 } 489 }
455}; 490};
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
index 7a500605e449..3cf2b7a12348 100644
--- a/drivers/crypto/padlock.h
+++ b/drivers/crypto/padlock.h
@@ -13,18 +13,18 @@
13#ifndef _CRYPTO_PADLOCK_H 13#ifndef _CRYPTO_PADLOCK_H
14#define _CRYPTO_PADLOCK_H 14#define _CRYPTO_PADLOCK_H
15 15
16#define PADLOCK_ALIGNMENT 16
17
16/* Control word. */ 18/* Control word. */
17union cword { 19struct cword {
18 uint32_t cword[4]; 20 int __attribute__ ((__packed__))
19 struct { 21 rounds:4,
20 int rounds:4; 22 algo:3,
21 int algo:3; 23 keygen:1,
22 int keygen:1; 24 interm:1,
23 int interm:1; 25 encdec:1,
24 int encdec:1; 26 ksize:2;
25 int ksize:2; 27} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));
26 } b;
27};
28 28
29#define PFX "padlock: " 29#define PFX "padlock: "
30 30