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