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