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