Line data Source code
1 : /* Padlock accelerated AES for Libgcrypt
2 : * Copyright (C) 2000, 2001, 2002, 2003, 2007,
3 : * 2008, 2011, 2012 Free Software Foundation, Inc.
4 : *
5 : * This file is part of Libgcrypt.
6 : *
7 : * Libgcrypt is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU Lesser General Public License as
9 : * published by the Free Software Foundation; either version 2.1 of
10 : * the License, or (at your option) any later version.
11 : *
12 : * Libgcrypt is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public
18 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h> /* for memcmp() */
25 :
26 : #include "types.h" /* for byte and u32 typedefs */
27 : #include "g10lib.h"
28 : #include "cipher.h"
29 : #include "bufhelp.h"
30 : #include "cipher-selftest.h"
31 : #include "rijndael-internal.h"
32 :
33 : #ifdef USE_PADLOCK
34 :
35 : /* Encrypt or decrypt one block using the padlock engine. A and B may
36 : be the same. */
37 : static unsigned int
38 0 : do_padlock (const RIJNDAEL_context *ctx, unsigned char *bx,
39 : const unsigned char *ax, int decrypt_flag)
40 : {
41 : /* BX and AX are not necessary correctly aligned. Thus we need to
42 : copy them here. */
43 : unsigned char a[16] __attribute__ ((aligned (16)));
44 : unsigned char b[16] __attribute__ ((aligned (16)));
45 : unsigned int cword[4] __attribute__ ((aligned (16)));
46 : int blocks;
47 :
48 : /* The control word fields are:
49 : 127:12 11:10 9 8 7 6 5 4 3:0
50 : RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */
51 0 : cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */
52 0 : cword[1] = 0;
53 0 : cword[2] = 0;
54 0 : cword[3] = 0;
55 0 : if (decrypt_flag)
56 0 : cword[0] |= 0x00000200;
57 :
58 0 : memcpy (a, ax, 16);
59 :
60 0 : blocks = 1; /* Init counter for just one block. */
61 : #ifdef __x86_64__
62 0 : asm volatile
63 : ("pushfq\n\t" /* Force key reload. */
64 : "popfq\n\t"
65 : ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
66 : : /* No output */
67 : : "S" (a), "D" (b), "d" (cword), "b" (ctx->padlockkey), "c" (blocks)
68 : : "cc", "memory"
69 : );
70 : #else
71 : asm volatile
72 : ("pushfl\n\t" /* Force key reload. */
73 : "popfl\n\t"
74 : "xchg %3, %%ebx\n\t" /* Load key. */
75 : ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XCRYPT ECB. */
76 : "xchg %3, %%ebx\n" /* Restore GOT register. */
77 : : /* No output */
78 : : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey), "c" (blocks)
79 : : "cc", "memory"
80 : );
81 : #endif
82 :
83 0 : memcpy (bx, b, 16);
84 :
85 0 : return (48 + 15 /* possible padding for alignment */);
86 : }
87 :
88 : unsigned int
89 0 : _gcry_aes_padlock_encrypt (const RIJNDAEL_context *ctx,
90 : unsigned char *bx, const unsigned char *ax)
91 : {
92 0 : return do_padlock(ctx, bx, ax, 0);
93 : }
94 :
95 : unsigned int
96 0 : _gcry_aes_padlock_decrypt (const RIJNDAEL_context *ctx,
97 : unsigned char *bx, const unsigned char *ax)
98 : {
99 0 : return do_padlock(ctx, bx, ax, 1);
100 : }
101 :
102 : #endif /* USE_PADLOCK */
|