4f64a06fb08a7c5df15473512ccc4138b1b0f32e
[openssl.git] / crypto / engine / eng_padlock.c
1 /* 
2  * Support for VIA PadLock Advanced Cryptography Engine (ACE)
3  * Written by Michal Ludvig <michal@logix.cz>
4  *            http://www.logix.cz/michal
5  *
6  * Big thanks to Andy Polyakov for a help with optimization, 
7  * assembler fixes, port to MS Windows and a lot of other 
8  * valuable work on this engine!
9  */
10
11 /* ====================================================================
12  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  *
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in
23  *    the documentation and/or other materials provided with the
24  *    distribution.
25  *
26  * 3. All advertising materials mentioning features or use of this
27  *    software must display the following acknowledgment:
28  *    "This product includes software developed by the OpenSSL Project
29  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
30  *
31  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
32  *    endorse or promote products derived from this software without
33  *    prior written permission. For written permission, please contact
34  *    licensing@OpenSSL.org.
35  *
36  * 5. Products derived from this software may not be called "OpenSSL"
37  *    nor may "OpenSSL" appear in their names without prior written
38  *    permission of the OpenSSL Project.
39  *
40  * 6. Redistributions of any form whatsoever must retain the following
41  *    acknowledgment:
42  *    "This product includes software developed by the OpenSSL Project
43  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
44  *
45  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
46  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
49  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56  * OF THE POSSIBILITY OF SUCH DAMAGE.
57  * ====================================================================
58  *
59  * This product includes cryptographic software written by Eric Young
60  * (eay@cryptsoft.com).  This product includes software written by Tim
61  * Hudson (tjh@cryptsoft.com).
62  *
63  */
64
65
66 #include <stdio.h>
67 #include <string.h>
68
69 #include <openssl/crypto.h>
70 #include <openssl/dso.h>
71 #include <openssl/engine.h>
72 #include <openssl/evp.h>
73 #include <openssl/aes.h>
74 #include <openssl/rand.h>
75
76 #ifndef OPENSSL_NO_HW
77 #ifndef OPENSSL_NO_HW_PADLOCK
78
79 /* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
80 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
81 #  ifndef OPENSSL_NO_DYNAMIC_ENGINE
82 #    define DYNAMIC_ENGINE
83 #  endif
84 #elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
85 #  ifdef ENGINE_DYNAMIC_SUPPORT
86 #    define DYNAMIC_ENGINE
87 #  endif
88 #else
89 #  error "Only OpenSSL >= 0.9.7 is supported"
90 #endif
91
92 /* VIA PadLock AES is available *ONLY* on some x86 CPUs.
93    Not only that it doesn't exist elsewhere, but it
94    even can't be compiled on other platforms!
95  
96    In addition, because of the heavy use of inline assembler,
97    compiler choice is limited to GCC and Microsoft C. */
98 #undef COMPILE_HW_PADLOCK
99 #if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
100 # if defined(__i386__) || defined(__i386) || defined(_M_IX86)
101 #  define COMPILE_HW_PADLOCK
102 static ENGINE *ENGINE_padlock (void);
103 # endif
104 #endif
105
106 void ENGINE_load_padlock (void)
107 {
108 /* On non-x86 CPUs it just returns. */
109 #ifdef COMPILE_HW_PADLOCK
110         ENGINE *toadd = ENGINE_padlock ();
111         if (!toadd) return;
112         ENGINE_add (toadd);
113         ENGINE_free (toadd);
114         ERR_clear_error ();
115 #endif
116 }
117
118 #ifdef COMPILE_HW_PADLOCK
119 /* We do these includes here to avoid header problems on platforms that
120    do not have the VIA padlock anyway... */
121 #ifdef _MSC_VER
122 # include <malloc.h>
123 # define alloca _alloca
124 #else
125 # include <stdlib.h>
126 #endif
127
128 /* Function for ENGINE detection and control */
129 static int padlock_available(void);
130 static int padlock_init(ENGINE *e);
131
132 /* RNG Stuff */
133 static RAND_METHOD padlock_rand;
134
135 /* Cipher Stuff */
136 static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
137
138 /* Engine names */
139 static const char *padlock_id = "padlock";
140 static char padlock_name[100];
141
142 /* Available features */
143 static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
144 static int padlock_use_rng = 0; /* Random Number Generator */
145 static int padlock_aes_align_required = 1;
146
147 /* ===== Engine "management" functions ===== */
148
149 /* Prepare the ENGINE structure for registration */
150 static int
151 padlock_bind_helper(ENGINE *e)
152 {
153         /* Check available features */
154         padlock_available();
155
156 #if 1   /* disable RNG for now, see commentary in vicinity of RNG code */
157         padlock_use_rng=0;
158 #endif
159
160         /* Generate a nice engine name with available features */
161         BIO_snprintf(padlock_name, sizeof(padlock_name),
162                 "VIA PadLock (%s, %s)", 
163                  padlock_use_rng ? "RNG" : "no-RNG",
164                  padlock_use_ace ? "ACE" : "no-ACE");
165
166         /* Register everything or return with an error */ 
167         if (!ENGINE_set_id(e, padlock_id) ||
168             !ENGINE_set_name(e, padlock_name) ||
169
170             !ENGINE_set_init_function(e, padlock_init) ||
171
172             (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
173             (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
174                 return 0;
175         }
176
177         /* Everything looks good */
178         return 1;
179 }
180
181 /* Constructor */
182 static ENGINE *
183 ENGINE_padlock(void)
184 {
185         ENGINE *eng = ENGINE_new();
186
187         if (!eng) {
188                 return NULL;
189         }
190
191         if (!padlock_bind_helper(eng)) {
192                 ENGINE_free(eng);
193                 return NULL;
194         }
195
196         return eng;
197 }
198
199 /* Check availability of the engine */
200 static int
201 padlock_init(ENGINE *e)
202 {
203         return (padlock_use_rng || padlock_use_ace);
204 }
205
206 /* This stuff is needed if this ENGINE is being compiled into a self-contained
207  * shared-library.
208  */
209 #ifdef DYNAMIC_ENGINE
210 static int
211 padlock_bind_fn(ENGINE *e, const char *id)
212 {
213         if (id && (strcmp(id, padlock_id) != 0)) {
214                 return 0;
215         }
216
217         if (!padlock_bind_helper(e))  {
218                 return 0;
219         }
220
221         return 1;
222 }
223
224 IMPLEMENT_DYNAMIC_CHECK_FN ();
225 IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn);
226 #endif /* DYNAMIC_ENGINE */
227
228 /* ===== Here comes the "real" engine ===== */
229
230 /* Some AES-related constants */
231 #define AES_BLOCK_SIZE          16
232 #define AES_KEY_SIZE_128        16
233 #define AES_KEY_SIZE_192        24
234 #define AES_KEY_SIZE_256        32
235
236 /* Here we store the status information relevant to the 
237    current context. */
238 /* BIG FAT WARNING:
239  *      Inline assembler in PADLOCK_XCRYPT_ASM()
240  *      depends on the order of items in this structure.
241  *      Don't blindly modify, reorder, etc!
242  */
243 struct padlock_cipher_data
244 {
245         unsigned char iv[AES_BLOCK_SIZE];       /* Initialization vector */
246         union { unsigned int pad[4];
247                 struct {
248                         int rounds:4;
249                         int algo:3;
250                         int keygen:1;
251                         int interm:1;
252                         int encdec:1;
253                         int ksize:2;
254                 } b;
255         } cword;                /* Control word */
256         AES_KEY ks;             /* Encryption key */
257 };
258
259 /*
260  * Essentially this variable belongs in thread local storage.
261  * Having this variable global on the other hand can only cause
262  * few bogus key reloads [if any at all on single-CPU system],
263  * so we accept the penatly...
264  */
265 static volatile struct padlock_cipher_data *padlock_saved_context;
266
267 /*
268  * =======================================================
269  * Inline assembler section(s).
270  * =======================================================
271  * Order of arguments is chosen to facilitate Windows port
272  * using __fastcall calling convention. If you wish to add
273  * more routines, keep in mind that first __fastcall
274  * argument is passed in %ecx and second - in %edx.
275  * =======================================================
276  */
277 #if defined(__GNUC__) && __GNUC__>=2
278 /*
279  * As for excessive "push %ebx"/"pop %ebx" found all over.
280  * When generating position-independent code GCC won't let
281  * us use "b" in assembler templates nor even respect "ebx"
282  * in "clobber description." Therefore the trouble...
283  */
284
285 /* Helper function - check if a CPUID instruction
286    is available on this CPU */
287 static int
288 padlock_insn_cpuid_available(void)
289 {
290         int result = -1;
291
292         /* We're checking if the bit #21 of EFLAGS 
293            can be toggled. If yes = CPUID is available. */
294         asm volatile (
295                 "pushf\n"
296                 "popl %%eax\n"
297                 "xorl $0x200000, %%eax\n"
298                 "movl %%eax, %%ecx\n"
299                 "andl $0x200000, %%ecx\n"
300                 "pushl %%eax\n"
301                 "popf\n"
302                 "pushf\n"
303                 "popl %%eax\n"
304                 "andl $0x200000, %%eax\n"
305                 "xorl %%eax, %%ecx\n"
306                 "movl %%ecx, %0\n"
307                 : "=r" (result) : : "eax", "ecx");
308         
309         return (result == 0);
310 }
311
312 /* Load supported features of the CPU to see if
313    the PadLock is available. */
314 static int
315 padlock_available(void)
316 {
317         char vendor_string[16];
318         unsigned int eax, edx;
319
320         /* First check if the CPUID instruction is available at all... */
321         if (! padlock_insn_cpuid_available())
322                 return 0;
323
324         /* Are we running on the Centaur (VIA) CPU? */
325         eax = 0x00000000;
326         vendor_string[12] = 0;
327         asm volatile (
328                 "pushl  %%ebx\n"
329                 "cpuid\n"
330                 "movl   %%ebx,(%%edi)\n"
331                 "movl   %%edx,4(%%edi)\n"
332                 "movl   %%ecx,8(%%edi)\n"
333                 "popl   %%ebx"
334                 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
335         if (strcmp(vendor_string, "CentaurHauls") != 0)
336                 return 0;
337
338         /* Check for Centaur Extended Feature Flags presence */
339         eax = 0xC0000000;
340         asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
341                 : "+a"(eax) : : "ecx", "edx");
342         if (eax < 0xC0000001)
343                 return 0;
344
345         /* Read the Centaur Extended Feature Flags */
346         eax = 0xC0000001;
347         asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
348                 : "+a"(eax), "=d"(edx) : : "ecx");
349
350         /* Fill up some flags */
351         padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
352         padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
353
354         return padlock_use_ace + padlock_use_rng;
355 }
356
357 /* Our own htonl()/ntohl() */
358 static inline void
359 padlock_bswapl(AES_KEY *ks)
360 {
361         size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
362         unsigned int *key = ks->rd_key;
363
364         while (i--) {
365                 asm volatile ("bswapl %0" : "+r"(*key));
366                 key++;
367         }
368 }
369
370 /* Force key reload from memory to the CPU microcode.
371    Loading EFLAGS from the stack clears EFLAGS[30] 
372    which does the trick. */
373 static inline void
374 padlock_reload_key(void)
375 {
376         asm volatile ("pushfl; popfl");
377 }
378
379 /*
380  * This is heuristic key context tracing. At first one
381  * believes that one should use atomic swap instructions,
382  * but it's not actually necessary. Point is that if
383  * padlock_saved_context was changed by another thread
384  * after we've read it and before we compare it with cdata,
385  * our key *shall* be reloaded upon thread context switch
386  * and we are therefore set in either case...
387  */
388 static inline void
389 padlock_verify_context(struct padlock_cipher_data *cdata)
390 {
391         asm volatile (
392         "pushfl\n"
393 "       bt      $30,(%%esp)\n"
394 "       jnc     1f\n"
395 "       cmp     %2,%1\n"
396 "       je      1f\n"
397 "       mov     %2,%0\n"
398 "       popfl\n"
399 "       sub     $4,%%esp\n"
400 "1:     add     $4,%%esp"
401         :"+m"(padlock_saved_context)
402         : "r"(padlock_saved_context), "r"(cdata) : "cc");
403 }
404
405 /* Template for padlock_xcrypt_* modes */
406 /* BIG FAT WARNING: 
407  *      The offsets used with 'leal' instructions
408  *      describe items of the 'padlock_cipher_data'
409  *      structure.
410  */
411 #define PADLOCK_XCRYPT_ASM(name,rep_xcrypt)     \
412 static inline void *name(size_t cnt,            \
413         struct padlock_cipher_data *cdata,      \
414         void *out, const void *inp)             \
415 {       void *iv;                               \
416         asm volatile ( "pushl   %%ebx\n"        \
417                 "       leal    16(%0),%%edx\n" \
418                 "       leal    32(%0),%%ebx\n" \
419                         rep_xcrypt "\n"         \
420                 "       popl    %%ebx"          \
421                 : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
422                 : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
423                 : "edx", "cc");                 \
424         return iv;                              \
425 }
426
427 /* Generate all functions with appropriate opcodes */
428 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8")     /* rep xcryptecb */
429 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0")     /* rep xcryptcbc */
430 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0")     /* rep xcryptcfb */
431 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8")     /* rep xcryptofb */
432
433 /* The RNG call itself */
434 static inline unsigned int
435 padlock_xstore(void *addr, unsigned int edx_in)
436 {
437         unsigned int eax_out;
438
439         asm volatile (".byte 0x0f,0xa7,0xc0"    /* xstore */
440             : "=a"(eax_out),"=m"(*(unsigned *)addr)
441             : "D"(addr), "d" (edx_in)
442             );
443
444         return eax_out;
445 }
446
447 /* Why not inline 'rep movsd'? I failed to find information on what
448  * value in Direction Flag one can expect and consequently have to
449  * apply "better-safe-than-sorry" approach and assume "undefined."
450  * I could explicitly clear it and restore the original value upon
451  * return from padlock_aes_cipher, but it's presumably too much
452  * trouble for too little gain...
453  *
454  * In case you wonder 'rep xcrypt*' instructions above are *not*
455  * affected by the Direction Flag and pointers advance toward
456  * larger addresses unconditionally.
457  */ 
458 static inline unsigned char *
459 padlock_memcpy(void *dst,const void *src,size_t n)
460 {
461         long       *d=dst;
462         const long *s=src;
463
464         n /= sizeof(*d);
465         do { *d++ = *s++; } while (--n);
466
467         return dst;
468 }
469
470 #elif defined(_MSC_VER)
471 /*
472  * Unlike GCC these are real functions. In order to minimize impact
473  * on performance we adhere to __fastcall calling convention in
474  * order to get two first arguments passed through %ecx and %edx.
475  * Which kind of suits very well, as instructions in question use
476  * both %ecx and %edx as input:-)
477  */
478 #define REP_XCRYPT(code)                \
479         _asm _emit 0xf3                 \
480         _asm _emit 0x0f _asm _emit 0xa7 \
481         _asm _emit code
482
483 /* BIG FAT WARNING: 
484  *      The offsets used with 'lea' instructions
485  *      describe items of the 'padlock_cipher_data'
486  *      structure.
487  */
488 #define PADLOCK_XCRYPT_ASM(name,code)   \
489 static void * __fastcall                \
490         name (size_t cnt, void *cdata,  \
491         void *outp, const void *inp)    \
492 {       _asm    mov     eax,edx         \
493         _asm    lea     edx,[eax+16]    \
494         _asm    lea     ebx,[eax+32]    \
495         _asm    mov     edi,outp        \
496         _asm    mov     esi,inp         \
497         REP_XCRYPT(code)                \
498 }
499
500 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
501 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
502 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
503 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
504
505 static int __fastcall
506 padlock_xstore(void *outp,unsigned int code)
507 {       _asm    mov     edi,ecx
508         _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
509 }
510
511 static void __fastcall
512 padlock_reload_key(void)
513 {       _asm pushfd _asm popfd          }
514
515 static void __fastcall
516 padlock_verify_context(void *cdata)
517 {       _asm    {
518                 pushfd
519                 bt      DWORD PTR[esp],30
520                 jnc     skip
521                 cmp     ecx,padlock_saved_context
522                 je      skip
523                 mov     padlock_saved_context,ecx
524                 popfd
525                 sub     esp,4
526         skip:   add     esp,4
527                 }
528 }
529
530 static int
531 padlock_available(void)
532 {       _asm    {
533                 pushfd
534                 pop     eax
535                 mov     ecx,eax
536                 xor     eax,1<<21
537                 push    eax
538                 popfd
539                 pushfd
540                 pop     eax
541                 xor     eax,ecx
542                 bt      eax,21
543                 jnc     noluck
544                 mov     eax,0
545                 cpuid
546                 xor     eax,eax
547                 cmp     ebx,'tneC'
548                 jne     noluck
549                 cmp     edx,'Hrua'
550                 jne     noluck
551                 cmp     ecx,'slua'
552                 jne     noluck
553                 mov     eax,0xC0000000
554                 cpuid
555                 mov     edx,eax
556                 xor     eax,eax
557                 cmp     edx,0xC0000001
558                 jb      noluck
559                 mov     eax,0xC0000001
560                 cpuid
561                 xor     eax,eax
562                 bt      edx,6
563                 jnc     skip_a
564                 bt      edx,7
565                 jnc     skip_a
566                 mov     padlock_use_ace,1
567                 inc     eax
568         skip_a: bt      edx,2
569                 jnc     skip_r
570                 bt      edx,3
571                 jnc     skip_r
572                 mov     padlock_use_rng,1
573                 inc     eax
574         skip_r:
575         noluck:
576                 }
577 }
578
579 static void __fastcall
580 padlock_bswapl(void *key)
581 {       _asm    {
582                 pushfd
583                 cld
584                 mov     esi,ecx
585                 mov     edi,ecx
586                 mov     ecx,60
587         up:     lodsd
588                 bswap   eax
589                 stosd
590                 loop    up
591                 popfd
592                 }
593 }
594
595 /* MS actually specifies status of Direction Flag and compiler even
596  * manages to compile following as 'rep movsd' all by itself...
597  */
598 #define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
599 #endif
600
601 /* ===== AES encryption/decryption ===== */
602
603 #if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
604 #define NID_aes_128_cfb NID_aes_128_cfb128
605 #endif
606
607 #if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
608 #define NID_aes_128_ofb NID_aes_128_ofb128
609 #endif
610
611 #if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
612 #define NID_aes_192_cfb NID_aes_192_cfb128
613 #endif
614
615 #if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
616 #define NID_aes_192_ofb NID_aes_192_ofb128
617 #endif
618
619 #if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
620 #define NID_aes_256_cfb NID_aes_256_cfb128
621 #endif
622
623 #if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
624 #define NID_aes_256_ofb NID_aes_256_ofb128
625 #endif
626
627 /* List of supported ciphers. */
628 static int padlock_cipher_nids[] = {
629         NID_aes_128_ecb,
630         NID_aes_128_cbc,
631         NID_aes_128_cfb,
632         NID_aes_128_ofb,
633
634         NID_aes_192_ecb,
635         NID_aes_192_cbc,
636 #if 0
637         NID_aes_192_cfb,        /* FIXME: AES192/256 CFB/OFB don't work. */
638         NID_aes_192_ofb,
639 #endif
640
641         NID_aes_256_ecb,
642         NID_aes_256_cbc,
643 #if 0
644         NID_aes_256_cfb,
645         NID_aes_256_ofb,
646 #endif
647 };
648 static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
649                                       sizeof(padlock_cipher_nids[0]));
650
651 /* Function prototypes ... */
652 static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
653                                 const unsigned char *iv, int enc);
654 static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
655                               const unsigned char *in, size_t nbytes);
656
657 #define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) +         \
658         ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F )      )
659 #define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
660         NEAREST_ALIGNED(ctx->cipher_data))
661
662 /* Declaring so many ciphers by hand would be a pain.
663    Instead introduce a bit of preprocessor magic :-) */
664 #define DECLARE_AES_EVP(ksize,lmode,umode)      \
665 static const EVP_CIPHER padlock_aes_##ksize##_##lmode = {       \
666         NID_aes_##ksize##_##lmode,              \
667         AES_BLOCK_SIZE,                 \
668         AES_KEY_SIZE_##ksize,           \
669         AES_BLOCK_SIZE,                 \
670         0 | EVP_CIPH_##umode##_MODE,    \
671         padlock_aes_init_key,           \
672         padlock_aes_cipher,             \
673         NULL,                           \
674         sizeof(struct padlock_cipher_data) + 16,        \
675         EVP_CIPHER_set_asn1_iv,         \
676         EVP_CIPHER_get_asn1_iv,         \
677         NULL,                           \
678         NULL                            \
679 }
680
681 DECLARE_AES_EVP(128,ecb,ECB);
682 DECLARE_AES_EVP(128,cbc,CBC);
683 DECLARE_AES_EVP(128,cfb,CFB);
684 DECLARE_AES_EVP(128,ofb,OFB);
685
686 DECLARE_AES_EVP(192,ecb,ECB);
687 DECLARE_AES_EVP(192,cbc,CBC);
688 DECLARE_AES_EVP(192,cfb,CFB);
689 DECLARE_AES_EVP(192,ofb,OFB);
690
691 DECLARE_AES_EVP(256,ecb,ECB);
692 DECLARE_AES_EVP(256,cbc,CBC);
693 DECLARE_AES_EVP(256,cfb,CFB);
694 DECLARE_AES_EVP(256,ofb,OFB);
695
696 static int
697 padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
698 {
699         /* No specific cipher => return a list of supported nids ... */
700         if (!cipher) {
701                 *nids = padlock_cipher_nids;
702                 return padlock_cipher_nids_num;
703         }
704
705         /* ... or the requested "cipher" otherwise */
706         switch (nid) {
707           case NID_aes_128_ecb:
708             *cipher = &padlock_aes_128_ecb;
709             break;
710           case NID_aes_128_cbc:
711             *cipher = &padlock_aes_128_cbc;
712             break;
713           case NID_aes_128_cfb:
714             *cipher = &padlock_aes_128_cfb;
715             break;
716           case NID_aes_128_ofb:
717             *cipher = &padlock_aes_128_ofb;
718             break;
719
720           case NID_aes_192_ecb:
721             *cipher = &padlock_aes_192_ecb;
722             break;
723           case NID_aes_192_cbc:
724             *cipher = &padlock_aes_192_cbc;
725             break;
726           case NID_aes_192_cfb:
727             *cipher = &padlock_aes_192_cfb;
728             break;
729           case NID_aes_192_ofb:
730             *cipher = &padlock_aes_192_ofb;
731             break;
732
733           case NID_aes_256_ecb:
734             *cipher = &padlock_aes_256_ecb;
735             break;
736           case NID_aes_256_cbc:
737             *cipher = &padlock_aes_256_cbc;
738             break;
739           case NID_aes_256_cfb:
740             *cipher = &padlock_aes_256_cfb;
741             break;
742           case NID_aes_256_ofb:
743             *cipher = &padlock_aes_256_ofb;
744             break;
745
746           default:
747             /* Sorry, we don't support this NID */
748             *cipher = NULL;
749             return 0;
750         }
751
752         return 1;
753 }
754
755 /* Prepare the encryption key for PadLock usage */
756 static int
757 padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
758                       const unsigned char *iv, int enc)
759 {
760         struct padlock_cipher_data *cdata;
761         int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
762
763         if (key==NULL) return 0;        /* ERROR */
764
765         cdata = ALIGNED_CIPHER_DATA(ctx);
766         memset(cdata, 0, sizeof(struct padlock_cipher_data));
767
768         /* Prepare Control word. */
769         cdata->cword.b.encdec = (ctx->encrypt == 0);
770         cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
771         cdata->cword.b.ksize = (key_len - 128) / 64;
772
773         switch(key_len) {
774                 case 128:
775                         /* PadLock can generate an extended key for
776                            AES128 in hardware */
777                         memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
778                         cdata->cword.b.keygen = 0;
779                         break;
780
781                 case 192:
782                 case 256:
783                         /* Generate an extended AES key in software.
784                            Needed for AES192/AES256 */
785                         /* Well, the above applies to Stepping 8 CPUs
786                            and is listed as hardware errata. They most
787                            likely will fix it at some point and then
788                            a check for stepping would be due here. */
789                         if (enc)
790                                 AES_set_encrypt_key(key, key_len, &cdata->ks);
791                         else
792                                 AES_set_decrypt_key(key, key_len, &cdata->ks);
793 #ifndef AES_ASM
794                         /* OpenSSL C functions use byte-swapped extended key. */
795                         padlock_bswapl(&cdata->ks);
796 #endif
797                         cdata->cword.b.keygen = 1;
798                         break;
799
800                 default:
801                         /* ERROR */
802                         return 0;
803         }
804
805         /*
806          * This is done to cover for cases when user reuses the
807          * context for new key. The catch is that if we don't do
808          * this, padlock_eas_cipher might proceed with old key...
809          */
810         padlock_reload_key ();
811
812         return 1;
813 }
814
815 /* 
816  * Simplified version of padlock_aes_cipher() used when
817  * 1) both input and output buffers are at aligned addresses.
818  * or when
819  * 2) running on a newer CPU that doesn't require aligned buffers.
820  */
821 static int
822 padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
823                 const unsigned char *in_arg, size_t nbytes)
824 {
825         struct padlock_cipher_data *cdata;
826         void  *iv;
827
828         cdata = ALIGNED_CIPHER_DATA(ctx);
829         padlock_verify_context(cdata);
830
831         switch (EVP_CIPHER_CTX_mode(ctx)) {
832         case EVP_CIPH_ECB_MODE:
833                 padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
834                 break;
835
836         case EVP_CIPH_CBC_MODE:
837                 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
838                 iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
839                 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
840                 break;
841
842         case EVP_CIPH_CFB_MODE:
843                 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
844                 iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
845                 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
846                 break;
847
848         case EVP_CIPH_OFB_MODE:
849                 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
850                 padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
851                 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
852                 break;
853
854         default:
855                 return 0;
856         }
857
858         memset(cdata->iv, 0, AES_BLOCK_SIZE);
859
860         return 1;
861 }
862
863 #ifndef  PADLOCK_CHUNK
864 # define PADLOCK_CHUNK  4096    /* Must be a power of 2 larger than 16 */
865 #endif
866 #if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
867 # error "insane PADLOCK_CHUNK..."
868 #endif
869
870 /* Re-align the arguments to 16-Bytes boundaries and run the 
871    encryption function itself. This function is not AES-specific. */
872 static int
873 padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
874                    const unsigned char *in_arg, size_t nbytes)
875 {
876         struct padlock_cipher_data *cdata;
877         const  void *inp;
878         unsigned char  *out;
879         void  *iv;
880         int    inp_misaligned, out_misaligned, realign_in_loop;
881         size_t chunk, allocated=0;
882
883         if (nbytes == 0)
884                 return 1;
885         if (nbytes % AES_BLOCK_SIZE)
886                 return 0; /* are we expected to do tail processing? */
887
888         /* VIA promises CPUs that won't require alignment in the future.
889            For now padlock_aes_align_required is initialized to 1 and
890            the condition is never met... */
891         if (!padlock_aes_align_required)
892                 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
893
894         inp_misaligned = (((size_t)in_arg) & 0x0F);
895         out_misaligned = (((size_t)out_arg) & 0x0F);
896
897         /* Note that even if output is aligned and input not,
898          * I still prefer to loop instead of copy the whole
899          * input and then encrypt in one stroke. This is done
900          * in order to improve L1 cache utilization... */
901         realign_in_loop = out_misaligned|inp_misaligned;
902
903         if (!realign_in_loop)
904                 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
905
906         /* this takes one "if" out of the loops */
907         chunk  = nbytes;
908         chunk %= PADLOCK_CHUNK;
909         if (chunk==0) chunk = PADLOCK_CHUNK;
910
911         if (out_misaligned) {
912                 /* optmize for small input */
913                 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
914                 out = alloca(0x10 + allocated);
915                 out = NEAREST_ALIGNED(out);
916         }
917         else
918                 out = out_arg;
919
920         cdata = ALIGNED_CIPHER_DATA(ctx);
921         padlock_verify_context(cdata);
922
923         switch (EVP_CIPHER_CTX_mode(ctx)) {
924         case EVP_CIPH_ECB_MODE:
925                 do      {
926                         if (inp_misaligned)
927                                 inp = padlock_memcpy(out, in_arg, chunk);
928                         else
929                                 inp = in_arg;
930                         in_arg += chunk;
931
932                         padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
933
934                         if (out_misaligned)
935                                 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
936                         else
937                                 out     = out_arg+=chunk;
938
939                         nbytes -= chunk;
940                         chunk   = PADLOCK_CHUNK;
941                 } while (nbytes);
942                 break;
943
944         case EVP_CIPH_CBC_MODE:
945                 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
946                 goto cbc_shortcut;
947                 do      {
948                         if (iv != cdata->iv)
949                                 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
950                         chunk = PADLOCK_CHUNK;
951                 cbc_shortcut: /* optimize for small input */
952                         if (inp_misaligned)
953                                 inp = padlock_memcpy(out, in_arg, chunk);
954                         else
955                                 inp = in_arg;
956                         in_arg += chunk;
957
958                         iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
959
960                         if (out_misaligned)
961                                 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
962                         else
963                                 out     = out_arg+=chunk;
964
965                 } while (nbytes -= chunk);
966                 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
967                 break;
968
969         case EVP_CIPH_CFB_MODE:
970                 memcpy (cdata->iv, ctx->iv, AES_BLOCK_SIZE);
971                 goto cfb_shortcut;
972                 do      {
973                         if (iv != cdata->iv)
974                                 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
975                         chunk = PADLOCK_CHUNK;
976                 cfb_shortcut: /* optimize for small input */
977                         if (inp_misaligned)
978                                 inp = padlock_memcpy(out, in_arg, chunk);
979                         else
980                                 inp = in_arg;
981                         in_arg += chunk;
982
983                         iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
984
985                         if (out_misaligned)
986                                 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
987                         else
988                                 out     = out_arg+=chunk;
989
990                 } while (nbytes -= chunk);
991                 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
992                 break;
993
994         case EVP_CIPH_OFB_MODE:
995                 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
996                 do      {
997                         if (inp_misaligned)
998                                 inp = padlock_memcpy(out, in_arg, chunk);
999                         else
1000                                 inp = in_arg;
1001                         in_arg += chunk;
1002
1003                         padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1004
1005                         if (out_misaligned)
1006                                 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1007                         else
1008                                 out     = out_arg+=chunk;
1009
1010                         nbytes -= chunk;
1011                         chunk   = PADLOCK_CHUNK;
1012                 } while (nbytes);
1013                 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
1014                 break;
1015
1016         default:
1017                 return 0;
1018         }
1019
1020         /* Clean the realign buffer if it was used */
1021         if (out_misaligned) {
1022                 volatile unsigned long *p=(void *)out;
1023                 size_t   n = allocated/sizeof(*p);
1024                 while (n--) *p++=0;
1025         }
1026
1027         memset(cdata->iv, 0, AES_BLOCK_SIZE);
1028
1029         return 1;
1030 }
1031
1032 /* ===== Random Number Generator ===== */
1033 /*
1034  * This code is not engaged. The reason is that it does not comply
1035  * with recommendations for VIA RNG usage for secure applications
1036  * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
1037  * provide meaningful error control...
1038  */
1039 /* Wrapper that provides an interface between the API and 
1040    the raw PadLock RNG */
1041 static int
1042 padlock_rand_bytes(unsigned char *output, int count)
1043 {
1044         unsigned int eax, buf;
1045
1046         while (count >= 8) {
1047                 eax = padlock_xstore(output, 0);
1048                 if (!(eax&(1<<6)))      return 0; /* RNG disabled */
1049                 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1050                 if (eax&(0x1F<<10))     return 0;
1051                 if ((eax&0x1F)==0)      continue; /* no data, retry... */
1052                 if ((eax&0x1F)!=8)      return 0; /* fatal failure...  */
1053                 output += 8;
1054                 count  -= 8;
1055         }
1056         while (count > 0) {
1057                 eax = padlock_xstore(&buf, 3);
1058                 if (!(eax&(1<<6)))      return 0; /* RNG disabled */
1059                 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1060                 if (eax&(0x1F<<10))     return 0;
1061                 if ((eax&0x1F)==0)      continue; /* no data, retry... */
1062                 if ((eax&0x1F)!=1)      return 0; /* fatal failure...  */
1063                 *output++ = (unsigned char)buf;
1064                 count--;
1065         }
1066         *(volatile unsigned int *)&buf=0;
1067
1068         return 1;
1069 }
1070
1071 /* Dummy but necessary function */
1072 static int
1073 padlock_rand_status(void)
1074 {
1075         return 1;
1076 }
1077
1078 /* Prepare structure for registration */
1079 static RAND_METHOD padlock_rand = {
1080         NULL,                   /* seed */
1081         padlock_rand_bytes,     /* bytes */
1082         NULL,                   /* cleanup */
1083         NULL,                   /* add */
1084         padlock_rand_bytes,     /* pseudorand */
1085         padlock_rand_status,    /* rand status */
1086 };
1087
1088 #endif /* COMPILE_HW_PADLOCK */
1089
1090 #endif /* !OPENSSL_NO_HW_PADLOCK */
1091 #endif /* !OPENSSL_NO_HW */