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