summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_padlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/eng_padlock.c')
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c496
1 files changed, 261 insertions, 235 deletions
diff --git a/src/lib/libcrypto/engine/eng_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c
index 0245f44de6..936a440b1a 100644
--- a/src/lib/libcrypto/engine/eng_padlock.c
+++ b/src/lib/libcrypto/engine/eng_padlock.c
@@ -1,11 +1,11 @@
1/* $OpenBSD: eng_padlock.c,v 1.10 2014/06/12 15:49:29 deraadt Exp $ */ 1/* $OpenBSD: eng_padlock.c,v 1.11 2014/06/22 12:05:09 jsing Exp $ */
2/* 2/*
3 * Support for VIA PadLock Advanced Cryptography Engine (ACE) 3 * Support for VIA PadLock Advanced Cryptography Engine (ACE)
4 * Written by Michal Ludvig <michal@logix.cz> 4 * Written by Michal Ludvig <michal@logix.cz>
5 * http://www.logix.cz/michal 5 * http://www.logix.cz/michal
6 * 6 *
7 * Big thanks to Andy Polyakov for a help with optimization, 7 * Big thanks to Andy Polyakov for a help with optimization,
8 * assembler fixes, port to MS Windows and a lot of other 8 * assembler fixes, port to MS Windows and a lot of other
9 * valuable work on this engine! 9 * valuable work on this engine!
10 */ 10 */
11 11
@@ -97,7 +97,7 @@
97/* VIA PadLock AES is available *ONLY* on some x86 CPUs. 97/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
98 Not only that it doesn't exist elsewhere, but it 98 Not only that it doesn't exist elsewhere, but it
99 even can't be compiled on other platforms! 99 even can't be compiled on other platforms!
100 100
101 In addition, because of the heavy use of inline assembler, 101 In addition, because of the heavy use of inline assembler,
102 compiler choice is limited to GCC and Microsoft C. */ 102 compiler choice is limited to GCC and Microsoft C. */
103#undef COMPILE_HW_PADLOCK 103#undef COMPILE_HW_PADLOCK
@@ -117,7 +117,8 @@ void ENGINE_load_padlock (void)
117/* On non-x86 CPUs it just returns. */ 117/* On non-x86 CPUs it just returns. */
118#ifdef COMPILE_HW_PADLOCK 118#ifdef COMPILE_HW_PADLOCK
119 ENGINE *toadd = ENGINE_padlock (); 119 ENGINE *toadd = ENGINE_padlock ();
120 if (!toadd) return; 120 if (!toadd)
121 return;
121 ENGINE_add (toadd); 122 ENGINE_add (toadd);
122 ENGINE_free (toadd); 123 ENGINE_free (toadd);
123 ERR_clear_error (); 124 ERR_clear_error ();
@@ -169,19 +170,18 @@ padlock_bind_helper(ENGINE *e)
169 padlock_available(); 170 padlock_available();
170 171
171#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */ 172#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
172 padlock_use_rng=0; 173 padlock_use_rng = 0;
173#endif 174#endif
174 175
175 /* Generate a nice engine name with available features */ 176 /* Generate a nice engine name with available features */
176 (void) snprintf(padlock_name, sizeof(padlock_name), 177 (void) snprintf(padlock_name, sizeof(padlock_name),
177 "VIA PadLock (%s, %s)", 178 "VIA PadLock (%s, %s)",
178 padlock_use_rng ? "RNG" : "no-RNG", 179 padlock_use_rng ? "RNG" : "no-RNG",
179 padlock_use_ace ? "ACE" : "no-ACE"); 180 padlock_use_ace ? "ACE" : "no-ACE");
180 181
181 /* Register everything or return with an error */ 182 /* Register everything or return with an error */
182 if (!ENGINE_set_id(e, padlock_id) || 183 if (!ENGINE_set_id(e, padlock_id) ||
183 !ENGINE_set_name(e, padlock_name) || 184 !ENGINE_set_name(e, padlock_name) ||
184
185 !ENGINE_set_init_function(e, padlock_init) || 185 !ENGINE_set_init_function(e, padlock_init) ||
186#ifndef OPENSSL_NO_AES 186#ifndef OPENSSL_NO_AES
187 (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) || 187 (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
@@ -254,26 +254,26 @@ IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
254#define AES_KEY_SIZE_192 24 254#define AES_KEY_SIZE_192 24
255#define AES_KEY_SIZE_256 32 255#define AES_KEY_SIZE_256 32
256 256
257/* Here we store the status information relevant to the 257/* Here we store the status information relevant to the
258 current context. */ 258 current context. */
259/* BIG FAT WARNING: 259/* BIG FAT WARNING:
260 * Inline assembler in PADLOCK_XCRYPT_ASM() 260 * Inline assembler in PADLOCK_XCRYPT_ASM()
261 * depends on the order of items in this structure. 261 * depends on the order of items in this structure.
262 * Don't blindly modify, reorder, etc! 262 * Don't blindly modify, reorder, etc!
263 */ 263 */
264struct padlock_cipher_data 264struct padlock_cipher_data {
265{
266 unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */ 265 unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
267 union { unsigned int pad[4]; 266 union {
267 unsigned int pad[4];
268 struct { 268 struct {
269 int rounds:4; 269 int rounds : 4;
270 int dgst:1; /* n/a in C3 */ 270 int dgst : 1; /* n/a in C3 */
271 int align:1; /* n/a in C3 */ 271 int align : 1; /* n/a in C3 */
272 int ciphr:1; /* n/a in C3 */ 272 int ciphr : 1; /* n/a in C3 */
273 unsigned int keygen:1; 273 unsigned int keygen : 1;
274 int interm:1; 274 int interm : 1;
275 unsigned int encdec:1; 275 unsigned int encdec : 1;
276 int ksize:2; 276 int ksize : 2;
277 } b; 277 } b;
278 } cword; /* Control word */ 278 } cword; /* Control word */
279 AES_KEY ks; /* Encryption key */ 279 AES_KEY ks; /* Encryption key */
@@ -313,23 +313,23 @@ padlock_insn_cpuid_available(void)
313{ 313{
314 int result = -1; 314 int result = -1;
315 315
316 /* We're checking if the bit #21 of EFLAGS 316 /* We're checking if the bit #21 of EFLAGS
317 can be toggled. If yes = CPUID is available. */ 317 can be toggled. If yes = CPUID is available. */
318 asm volatile ( 318 asm volatile (
319 "pushf\n" 319 "pushf\n"
320 "popl %%eax\n" 320 "popl %%eax\n"
321 "xorl $0x200000, %%eax\n" 321 "xorl $0x200000, %%eax\n"
322 "movl %%eax, %%ecx\n" 322 "movl %%eax, %%ecx\n"
323 "andl $0x200000, %%ecx\n" 323 "andl $0x200000, %%ecx\n"
324 "pushl %%eax\n" 324 "pushl %%eax\n"
325 "popf\n" 325 "popf\n"
326 "pushf\n" 326 "pushf\n"
327 "popl %%eax\n" 327 "popl %%eax\n"
328 "andl $0x200000, %%eax\n" 328 "andl $0x200000, %%eax\n"
329 "xorl %%eax, %%ecx\n" 329 "xorl %%eax, %%ecx\n"
330 "movl %%ecx, %0\n" 330 "movl %%ecx, %0\n"
331 : "=r" (result) : : "eax", "ecx"); 331 : "=r" (result) : : "eax", "ecx");
332 332
333 return (result == 0); 333 return (result == 0);
334} 334}
335 335
@@ -349,31 +349,31 @@ padlock_available(void)
349 eax = 0x00000000; 349 eax = 0x00000000;
350 vendor_string[12] = 0; 350 vendor_string[12] = 0;
351 asm volatile ( 351 asm volatile (
352 "pushl %%ebx\n" 352 "pushl %%ebx\n"
353 "cpuid\n" 353 "cpuid\n"
354 "movl %%ebx,(%%edi)\n" 354 "movl %%ebx,(%%edi)\n"
355 "movl %%edx,4(%%edi)\n" 355 "movl %%edx,4(%%edi)\n"
356 "movl %%ecx,8(%%edi)\n" 356 "movl %%ecx,8(%%edi)\n"
357 "popl %%ebx" 357 "popl %%ebx"
358 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx"); 358 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
359 if (strcmp(vendor_string, "CentaurHauls") != 0) 359 if (strcmp(vendor_string, "CentaurHauls") != 0)
360 return 0; 360 return 0;
361 361
362 /* Check for Centaur Extended Feature Flags presence */ 362 /* Check for Centaur Extended Feature Flags presence */
363 eax = 0xC0000000; 363 eax = 0xC0000000;
364 asm volatile ("pushl %%ebx; cpuid; popl %%ebx" 364 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
365 : "+a"(eax) : : "ecx", "edx"); 365 : "+a"(eax) : : "ecx", "edx");
366 if (eax < 0xC0000001) 366 if (eax < 0xC0000001)
367 return 0; 367 return 0;
368 368
369 /* Read the Centaur Extended Feature Flags */ 369 /* Read the Centaur Extended Feature Flags */
370 eax = 0xC0000001; 370 eax = 0xC0000001;
371 asm volatile ("pushl %%ebx; cpuid; popl %%ebx" 371 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
372 : "+a"(eax), "=d"(edx) : : "ecx"); 372 : "+a"(eax), "=d"(edx) : : "ecx");
373 373
374 /* Fill up some flags */ 374 /* Fill up some flags */
375 padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6)); 375 padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6));
376 padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2)); 376 padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2));
377 377
378 return padlock_use_ace + padlock_use_rng; 378 return padlock_use_ace + padlock_use_rng;
379} 379}
@@ -394,7 +394,7 @@ padlock_bswapl(AES_KEY *ks)
394#endif 394#endif
395 395
396/* Force key reload from memory to the CPU microcode. 396/* Force key reload from memory to the CPU microcode.
397 Loading EFLAGS from the stack clears EFLAGS[30] 397 Loading EFLAGS from the stack clears EFLAGS[30]
398 which does the trick. */ 398 which does the trick. */
399static inline void 399static inline void
400padlock_reload_key(void) 400padlock_reload_key(void)
@@ -416,21 +416,21 @@ static inline void
416padlock_verify_context(struct padlock_cipher_data *cdata) 416padlock_verify_context(struct padlock_cipher_data *cdata)
417{ 417{
418 asm volatile ( 418 asm volatile (
419 "pushfl\n" 419 "pushfl\n"
420" btl $30,(%%esp)\n" 420 " btl $30,(%%esp)\n"
421" jnc 1f\n" 421 " jnc 1f\n"
422" cmpl %2,%1\n" 422 " cmpl %2,%1\n"
423" je 1f\n" 423 " je 1f\n"
424" popfl\n" 424 " popfl\n"
425" subl $4,%%esp\n" 425 " subl $4,%%esp\n"
426"1: addl $4,%%esp\n" 426 "1: addl $4,%%esp\n"
427" movl %2,%0" 427 " movl %2,%0"
428 :"+m"(padlock_saved_context) 428 :"+m"(padlock_saved_context)
429 : "r"(padlock_saved_context), "r"(cdata) : "cc"); 429 : "r"(padlock_saved_context), "r"(cdata) : "cc");
430} 430}
431 431
432/* Template for padlock_xcrypt_* modes */ 432/* Template for padlock_xcrypt_* modes */
433/* BIG FAT WARNING: 433/* BIG FAT WARNING:
434 * The offsets used with 'leal' instructions 434 * The offsets used with 'leal' instructions
435 * describe items of the 'padlock_cipher_data' 435 * describe items of the 'padlock_cipher_data'
436 * structure. 436 * structure.
@@ -465,9 +465,9 @@ padlock_xstore(void *addr, unsigned int edx_in)
465 unsigned int eax_out; 465 unsigned int eax_out;
466 466
467 asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */ 467 asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
468 : "=a"(eax_out),"=m"(*(unsigned *)addr) 468 : "=a"(eax_out),"=m"(*(unsigned *)addr)
469 : "D"(addr), "d" (edx_in) 469 : "D"(addr), "d" (edx_in)
470 ); 470 );
471 471
472 return eax_out; 472 return eax_out;
473} 473}
@@ -482,15 +482,16 @@ padlock_xstore(void *addr, unsigned int edx_in)
482 * In case you wonder 'rep xcrypt*' instructions above are *not* 482 * In case you wonder 'rep xcrypt*' instructions above are *not*
483 * affected by the Direction Flag and pointers advance toward 483 * affected by the Direction Flag and pointers advance toward
484 * larger addresses unconditionally. 484 * larger addresses unconditionally.
485 */ 485 */
486static inline unsigned char * 486static inline unsigned char *
487padlock_memcpy(void *dst,const void *src,size_t n) 487padlock_memcpy(void *dst, const void *src, size_t n)
488{ 488{
489 long *d=dst; 489 long *d = dst;
490 const long *s=src; 490 const long *s = src;
491 491
492 n /= sizeof(*d); 492 n /= sizeof(*d);
493 do { *d++ = *s++; } while (--n); 493 do { *d++ = *s++;
494 } while (--n);
494 495
495 return dst; 496 return dst;
496} 497}
@@ -541,13 +542,13 @@ static int padlock_cipher_nids[] = {
541 NID_aes_256_ofb, 542 NID_aes_256_ofb,
542}; 543};
543static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/ 544static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
544 sizeof(padlock_cipher_nids[0])); 545sizeof(padlock_cipher_nids[0]));
545 546
546/* Function prototypes ... */ 547/* Function prototypes ... */
547static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 548static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
548 const unsigned char *iv, int enc); 549 const unsigned char *iv, int enc);
549static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 550static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
550 const unsigned char *in, size_t nbytes); 551 const unsigned char *in, size_t nbytes);
551 552
552#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \ 553#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
553 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) 554 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
@@ -578,23 +579,23 @@ static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
578 NULL \ 579 NULL \
579} 580}
580 581
581DECLARE_AES_EVP(128,ecb,ECB); 582DECLARE_AES_EVP(128, ecb, ECB);
582DECLARE_AES_EVP(128,cbc,CBC); 583DECLARE_AES_EVP(128, cbc, CBC);
583DECLARE_AES_EVP(128,cfb,CFB); 584DECLARE_AES_EVP(128, cfb, CFB);
584DECLARE_AES_EVP(128,ofb,OFB); 585DECLARE_AES_EVP(128, ofb, OFB);
585 586
586DECLARE_AES_EVP(192,ecb,ECB); 587DECLARE_AES_EVP(192, ecb, ECB);
587DECLARE_AES_EVP(192,cbc,CBC); 588DECLARE_AES_EVP(192, cbc, CBC);
588DECLARE_AES_EVP(192,cfb,CFB); 589DECLARE_AES_EVP(192, cfb, CFB);
589DECLARE_AES_EVP(192,ofb,OFB); 590DECLARE_AES_EVP(192, ofb, OFB);
590 591
591DECLARE_AES_EVP(256,ecb,ECB); 592DECLARE_AES_EVP(256, ecb, ECB);
592DECLARE_AES_EVP(256,cbc,CBC); 593DECLARE_AES_EVP(256, cbc, CBC);
593DECLARE_AES_EVP(256,cfb,CFB); 594DECLARE_AES_EVP(256, cfb, CFB);
594DECLARE_AES_EVP(256,ofb,OFB); 595DECLARE_AES_EVP(256, ofb, OFB);
595 596
596static int 597static int
597padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid) 598padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
598{ 599{
599 /* No specific cipher => return a list of supported nids ... */ 600 /* No specific cipher => return a list of supported nids ... */
600 if (!cipher) { 601 if (!cipher) {
@@ -604,49 +605,46 @@ padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid
604 605
605 /* ... or the requested "cipher" otherwise */ 606 /* ... or the requested "cipher" otherwise */
606 switch (nid) { 607 switch (nid) {
607 case NID_aes_128_ecb: 608 case NID_aes_128_ecb:
608 *cipher = &padlock_aes_128_ecb; 609 *cipher = &padlock_aes_128_ecb;
609 break; 610 break;
610 case NID_aes_128_cbc: 611 case NID_aes_128_cbc:
611 *cipher = &padlock_aes_128_cbc; 612 *cipher = &padlock_aes_128_cbc;
612 break; 613 break;
613 case NID_aes_128_cfb: 614 case NID_aes_128_cfb:
614 *cipher = &padlock_aes_128_cfb; 615 *cipher = &padlock_aes_128_cfb;
615 break; 616 break;
616 case NID_aes_128_ofb: 617 case NID_aes_128_ofb:
617 *cipher = &padlock_aes_128_ofb; 618 *cipher = &padlock_aes_128_ofb;
618 break; 619 break;
619 620 case NID_aes_192_ecb:
620 case NID_aes_192_ecb: 621 *cipher = &padlock_aes_192_ecb;
621 *cipher = &padlock_aes_192_ecb; 622 break;
622 break; 623 case NID_aes_192_cbc:
623 case NID_aes_192_cbc: 624 *cipher = &padlock_aes_192_cbc;
624 *cipher = &padlock_aes_192_cbc; 625 break;
625 break; 626 case NID_aes_192_cfb:
626 case NID_aes_192_cfb: 627 *cipher = &padlock_aes_192_cfb;
627 *cipher = &padlock_aes_192_cfb; 628 break;
628 break; 629 case NID_aes_192_ofb:
629 case NID_aes_192_ofb: 630 *cipher = &padlock_aes_192_ofb;
630 *cipher = &padlock_aes_192_ofb; 631 break;
631 break; 632 case NID_aes_256_ecb:
632 633 *cipher = &padlock_aes_256_ecb;
633 case NID_aes_256_ecb: 634 break;
634 *cipher = &padlock_aes_256_ecb; 635 case NID_aes_256_cbc:
635 break; 636 *cipher = &padlock_aes_256_cbc;
636 case NID_aes_256_cbc: 637 break;
637 *cipher = &padlock_aes_256_cbc; 638 case NID_aes_256_cfb:
638 break; 639 *cipher = &padlock_aes_256_cfb;
639 case NID_aes_256_cfb: 640 break;
640 *cipher = &padlock_aes_256_cfb; 641 case NID_aes_256_ofb:
641 break; 642 *cipher = &padlock_aes_256_ofb;
642 case NID_aes_256_ofb: 643 break;
643 *cipher = &padlock_aes_256_ofb; 644 default:
644 break; 645 /* Sorry, we don't support this NID */
645 646 *cipher = NULL;
646 default: 647 return 0;
647 /* Sorry, we don't support this NID */
648 *cipher = NULL;
649 return 0;
650 } 648 }
651 649
652 return 1; 650 return 1;
@@ -655,12 +653,13 @@ padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid
655/* Prepare the encryption key for PadLock usage */ 653/* Prepare the encryption key for PadLock usage */
656static int 654static int
657padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key, 655padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
658 const unsigned char *iv, int enc) 656 const unsigned char *iv, int enc)
659{ 657{
660 struct padlock_cipher_data *cdata; 658 struct padlock_cipher_data *cdata;
661 int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8; 659 int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
662 660
663 if (key==NULL) return 0; /* ERROR */ 661 if (key == NULL)
662 return 0; /* ERROR */
664 663
665 cdata = ALIGNED_CIPHER_DATA(ctx); 664 cdata = ALIGNED_CIPHER_DATA(ctx);
666 memset(cdata, 0, sizeof(struct padlock_cipher_data)); 665 memset(cdata, 0, sizeof(struct padlock_cipher_data));
@@ -673,38 +672,38 @@ padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
673 cdata->cword.b.rounds = 10 + (key_len - 128) / 32; 672 cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
674 cdata->cword.b.ksize = (key_len - 128) / 64; 673 cdata->cword.b.ksize = (key_len - 128) / 64;
675 674
676 switch(key_len) { 675 switch (key_len) {
677 case 128: 676 case 128:
678 /* PadLock can generate an extended key for 677 /* PadLock can generate an extended key for
679 AES128 in hardware */ 678 AES128 in hardware */
680 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128); 679 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
681 cdata->cword.b.keygen = 0; 680 cdata->cword.b.keygen = 0;
682 break; 681 break;
683 682
684 case 192: 683 case 192:
685 case 256: 684 case 256:
686 /* Generate an extended AES key in software. 685 /* Generate an extended AES key in software.
687 Needed for AES192/AES256 */ 686 Needed for AES192/AES256 */
688 /* Well, the above applies to Stepping 8 CPUs 687 /* Well, the above applies to Stepping 8 CPUs
689 and is listed as hardware errata. They most 688 and is listed as hardware errata. They most
690 likely will fix it at some point and then 689 likely will fix it at some point and then
691 a check for stepping would be due here. */ 690 a check for stepping would be due here. */
692 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE || 691 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
693 EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE || 692 EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
694 enc) 693 enc)
695 AES_set_encrypt_key(key, key_len, &cdata->ks); 694 AES_set_encrypt_key(key, key_len, &cdata->ks);
696 else 695 else
697 AES_set_decrypt_key(key, key_len, &cdata->ks); 696 AES_set_decrypt_key(key, key_len, &cdata->ks);
698#ifndef AES_ASM 697#ifndef AES_ASM
699 /* OpenSSL C functions use byte-swapped extended key. */ 698 /* OpenSSL C functions use byte-swapped extended key. */
700 padlock_bswapl(&cdata->ks); 699 padlock_bswapl(&cdata->ks);
701#endif 700#endif
702 cdata->cword.b.keygen = 1; 701 cdata->cword.b.keygen = 1;
703 break; 702 break;
704 703
705 default: 704 default:
706 /* ERROR */ 705 /* ERROR */
707 return 0; 706 return 0;
708 } 707 }
709 708
710 /* 709 /*
@@ -717,7 +716,7 @@ padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
717 return 1; 716 return 1;
718} 717}
719 718
720/* 719/*
721 * Simplified version of padlock_aes_cipher() used when 720 * Simplified version of padlock_aes_cipher() used when
722 * 1) both input and output buffers are at aligned addresses. 721 * 1) both input and output buffers are at aligned addresses.
723 * or when 722 * or when
@@ -725,7 +724,7 @@ padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
725 */ 724 */
726static int 725static int
727padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 726padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
728 const unsigned char *in_arg, size_t nbytes) 727 const unsigned char *in_arg, size_t nbytes)
729{ 728{
730 struct padlock_cipher_data *cdata; 729 struct padlock_cipher_data *cdata;
731 void *iv; 730 void *iv;
@@ -735,24 +734,28 @@ padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
735 734
736 switch (EVP_CIPHER_CTX_mode(ctx)) { 735 switch (EVP_CIPHER_CTX_mode(ctx)) {
737 case EVP_CIPH_ECB_MODE: 736 case EVP_CIPH_ECB_MODE:
738 padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); 737 padlock_xcrypt_ecb(nbytes / AES_BLOCK_SIZE, cdata,
738 out_arg, in_arg);
739 break; 739 break;
740 740
741 case EVP_CIPH_CBC_MODE: 741 case EVP_CIPH_CBC_MODE:
742 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); 742 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
743 iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); 743 iv = padlock_xcrypt_cbc(nbytes / AES_BLOCK_SIZE, cdata,
744 out_arg, in_arg);
744 memcpy(ctx->iv, iv, AES_BLOCK_SIZE); 745 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
745 break; 746 break;
746 747
747 case EVP_CIPH_CFB_MODE: 748 case EVP_CIPH_CFB_MODE:
748 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); 749 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
749 iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); 750 iv = padlock_xcrypt_cfb(nbytes / AES_BLOCK_SIZE, cdata,
751 out_arg, in_arg);
750 memcpy(ctx->iv, iv, AES_BLOCK_SIZE); 752 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
751 break; 753 break;
752 754
753 case EVP_CIPH_OFB_MODE: 755 case EVP_CIPH_OFB_MODE:
754 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); 756 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
755 padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); 757 padlock_xcrypt_ofb(nbytes / AES_BLOCK_SIZE, cdata,
758 out_arg, in_arg);
756 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); 759 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
757 break; 760 break;
758 761
@@ -772,23 +775,24 @@ padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
772# error "insane PADLOCK_CHUNK..." 775# error "insane PADLOCK_CHUNK..."
773#endif 776#endif
774 777
775/* Re-align the arguments to 16-Bytes boundaries and run the 778/* Re-align the arguments to 16-Bytes boundaries and run the
776 encryption function itself. This function is not AES-specific. */ 779 encryption function itself. This function is not AES-specific. */
777static int 780static int
778padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 781padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
779 const unsigned char *in_arg, size_t nbytes) 782 const unsigned char *in_arg, size_t nbytes)
780{ 783{
781 struct padlock_cipher_data *cdata; 784 struct padlock_cipher_data *cdata;
782 const void *inp; 785 const void *inp;
783 unsigned char *out; 786 unsigned char *out;
784 void *iv; 787 void *iv;
785 int inp_misaligned, out_misaligned, realign_in_loop; 788 int inp_misaligned, out_misaligned, realign_in_loop;
786 size_t chunk, allocated=0; 789 size_t chunk, allocated = 0;
787 790
788 /* ctx->num is maintained in byte-oriented modes, 791 /* ctx->num is maintained in byte-oriented modes,
789 such as CFB and OFB... */ 792 such as CFB and OFB... */
790 if ((chunk = ctx->num)) { /* borrow chunk variable */ 793 if ((chunk = ctx->num)) {
791 unsigned char *ivp=ctx->iv; 794 /* borrow chunk variable */
795 unsigned char *ivp = ctx->iv;
792 796
793 switch (EVP_CIPHER_CTX_mode(ctx)) { 797 switch (EVP_CIPHER_CTX_mode(ctx)) {
794 case EVP_CIPH_CFB_MODE: 798 case EVP_CIPH_CFB_MODE:
@@ -796,28 +800,29 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
796 return 0; /* bogus value */ 800 return 0; /* bogus value */
797 801
798 if (ctx->encrypt) 802 if (ctx->encrypt)
799 while (chunk<AES_BLOCK_SIZE && nbytes!=0) { 803 while (chunk < AES_BLOCK_SIZE && nbytes != 0) {
800 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk]; 804 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
801 chunk++, nbytes--; 805 chunk++, nbytes--;
802 } 806 }
803 else while (chunk<AES_BLOCK_SIZE && nbytes!=0) { 807 else
808 while (chunk < AES_BLOCK_SIZE && nbytes != 0) {
804 unsigned char c = *(in_arg++); 809 unsigned char c = *(in_arg++);
805 *(out_arg++) = c ^ ivp[chunk]; 810 *(out_arg++) = c ^ ivp[chunk];
806 ivp[chunk++] = c, nbytes--; 811 ivp[chunk++] = c, nbytes--;
807 } 812 }
808 813
809 ctx->num = chunk%AES_BLOCK_SIZE; 814 ctx->num = chunk % AES_BLOCK_SIZE;
810 break; 815 break;
811 case EVP_CIPH_OFB_MODE: 816 case EVP_CIPH_OFB_MODE:
812 if (chunk >= AES_BLOCK_SIZE) 817 if (chunk >= AES_BLOCK_SIZE)
813 return 0; /* bogus value */ 818 return 0; /* bogus value */
814 819
815 while (chunk<AES_BLOCK_SIZE && nbytes!=0) { 820 while (chunk < AES_BLOCK_SIZE && nbytes != 0) {
816 *(out_arg++) = *(in_arg++) ^ ivp[chunk]; 821 *(out_arg++) = *(in_arg++) ^ ivp[chunk];
817 chunk++, nbytes--; 822 chunk++, nbytes--;
818 } 823 }
819 824
820 ctx->num = chunk%AES_BLOCK_SIZE; 825 ctx->num = chunk % AES_BLOCK_SIZE;
821 break; 826 break;
822 } 827 }
823 } 828 }
@@ -841,8 +846,9 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
841 same as for software alignment below or ~3x. They promise to 846 same as for software alignment below or ~3x. They promise to
842 improve it in the future, but for now we can just as well 847 improve it in the future, but for now we can just as well
843 pretend that it can only handle aligned input... */ 848 pretend that it can only handle aligned input... */
844 if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0) 849 if (!padlock_aes_align_required && (nbytes % AES_BLOCK_SIZE) == 0)
845 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); 850 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg,
851 nbytes);
846 852
847 inp_misaligned = (((size_t)in_arg) & 0x0F); 853 inp_misaligned = (((size_t)in_arg) & 0x0F);
848 out_misaligned = (((size_t)out_arg) & 0x0F); 854 out_misaligned = (((size_t)out_arg) & 0x0F);
@@ -853,21 +859,22 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
853 * in order to improve L1 cache utilization... */ 859 * in order to improve L1 cache utilization... */
854 realign_in_loop = out_misaligned|inp_misaligned; 860 realign_in_loop = out_misaligned|inp_misaligned;
855 861
856 if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0) 862 if (!realign_in_loop && (nbytes % AES_BLOCK_SIZE) == 0)
857 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); 863 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg,
864 nbytes);
858 865
859 /* this takes one "if" out of the loops */ 866 /* this takes one "if" out of the loops */
860 chunk = nbytes; 867 chunk = nbytes;
861 chunk %= PADLOCK_CHUNK; 868 chunk %= PADLOCK_CHUNK;
862 if (chunk==0) chunk = PADLOCK_CHUNK; 869 if (chunk == 0)
870 chunk = PADLOCK_CHUNK;
863 871
864 if (out_misaligned) { 872 if (out_misaligned) {
865 /* optmize for small input */ 873 /* optmize for small input */
866 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes); 874 allocated = (chunk < nbytes ? PADLOCK_CHUNK : nbytes);
867 out = alloca(0x10 + allocated); 875 out = alloca(0x10 + allocated);
868 out = NEAREST_ALIGNED(out); 876 out = NEAREST_ALIGNED(out);
869 } 877 } else
870 else
871 out = out_arg; 878 out = out_arg;
872 879
873 cdata = ALIGNED_CIPHER_DATA(ctx); 880 cdata = ALIGNED_CIPHER_DATA(ctx);
@@ -875,77 +882,84 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
875 882
876 switch (EVP_CIPHER_CTX_mode(ctx)) { 883 switch (EVP_CIPHER_CTX_mode(ctx)) {
877 case EVP_CIPH_ECB_MODE: 884 case EVP_CIPH_ECB_MODE:
878 do { 885 do {
879 if (inp_misaligned) 886 if (inp_misaligned)
880 inp = padlock_memcpy(out, in_arg, chunk); 887 inp = padlock_memcpy(out, in_arg, chunk);
881 else 888 else
882 inp = in_arg; 889 inp = in_arg;
883 in_arg += chunk; 890 in_arg += chunk;
884 891
885 padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp); 892 padlock_xcrypt_ecb(chunk / AES_BLOCK_SIZE, cdata,
893 out, inp);
886 894
887 if (out_misaligned) 895 if (out_misaligned)
888 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; 896 out_arg = padlock_memcpy(out_arg, out, chunk) +
897 chunk;
889 else 898 else
890 out = out_arg+=chunk; 899 out = out_arg += chunk;
891 900
892 nbytes -= chunk; 901 nbytes -= chunk;
893 chunk = PADLOCK_CHUNK; 902 chunk = PADLOCK_CHUNK;
894 } while (nbytes); 903 } while (nbytes);
895 break; 904 break;
896 905
897 case EVP_CIPH_CBC_MODE: 906 case EVP_CIPH_CBC_MODE:
898 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); 907 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
899 goto cbc_shortcut; 908 goto cbc_shortcut;
900 do { 909 do {
901 if (iv != cdata->iv) 910 if (iv != cdata->iv)
902 memcpy(cdata->iv, iv, AES_BLOCK_SIZE); 911 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
903 chunk = PADLOCK_CHUNK; 912 chunk = PADLOCK_CHUNK;
904 cbc_shortcut: /* optimize for small input */ 913 cbc_shortcut: /* optimize for small input */
905 if (inp_misaligned) 914 if (inp_misaligned)
906 inp = padlock_memcpy(out, in_arg, chunk); 915 inp = padlock_memcpy(out, in_arg, chunk);
907 else 916 else
908 inp = in_arg; 917 inp = in_arg;
909 in_arg += chunk; 918 in_arg += chunk;
910 919
911 iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp); 920 iv = padlock_xcrypt_cbc(chunk / AES_BLOCK_SIZE, cdata,
921 out, inp);
912 922
913 if (out_misaligned) 923 if (out_misaligned)
914 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; 924 out_arg = padlock_memcpy(out_arg, out, chunk) +
925 chunk;
915 else 926 else
916 out = out_arg+=chunk; 927 out = out_arg += chunk;
917
918 } while (nbytes -= chunk); 928 } while (nbytes -= chunk);
919 memcpy(ctx->iv, iv, AES_BLOCK_SIZE); 929 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
920 break; 930 break;
921 931
922 case EVP_CIPH_CFB_MODE: 932 case EVP_CIPH_CFB_MODE:
923 memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE); 933 memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
924 chunk &= ~(AES_BLOCK_SIZE-1); 934 chunk &= ~(AES_BLOCK_SIZE - 1);
925 if (chunk) goto cfb_shortcut; 935 if (chunk)
926 else goto cfb_skiploop; 936 goto cfb_shortcut;
927 do { 937 else
938 goto cfb_skiploop;
939 do {
928 if (iv != cdata->iv) 940 if (iv != cdata->iv)
929 memcpy(cdata->iv, iv, AES_BLOCK_SIZE); 941 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
930 chunk = PADLOCK_CHUNK; 942 chunk = PADLOCK_CHUNK;
931 cfb_shortcut: /* optimize for small input */ 943 cfb_shortcut: /* optimize for small input */
932 if (inp_misaligned) 944 if (inp_misaligned)
933 inp = padlock_memcpy(out, in_arg, chunk); 945 inp = padlock_memcpy(out, in_arg, chunk);
934 else 946 else
935 inp = in_arg; 947 inp = in_arg;
936 in_arg += chunk; 948 in_arg += chunk;
937 949
938 iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp); 950 iv = padlock_xcrypt_cfb(chunk / AES_BLOCK_SIZE, cdata,
951 out, inp);
939 952
940 if (out_misaligned) 953 if (out_misaligned)
941 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; 954 out_arg = padlock_memcpy(out_arg, out, chunk) +
955 chunk;
942 else 956 else
943 out = out_arg+=chunk; 957 out = out_arg += chunk;
944 958
945 nbytes -= chunk; 959 nbytes -= chunk;
946 } while (nbytes >= AES_BLOCK_SIZE); 960 } while (nbytes >= AES_BLOCK_SIZE);
947 961
948 cfb_skiploop: 962cfb_skiploop:
949 if (nbytes) { 963 if (nbytes) {
950 unsigned char *ivp = cdata->iv; 964 unsigned char *ivp = cdata->iv;
951 965
@@ -955,19 +969,19 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
955 } 969 }
956 ctx->num = nbytes; 970 ctx->num = nbytes;
957 if (cdata->cword.b.encdec) { 971 if (cdata->cword.b.encdec) {
958 cdata->cword.b.encdec=0; 972 cdata->cword.b.encdec = 0;
959 padlock_reload_key(); 973 padlock_reload_key();
960 padlock_xcrypt_ecb(1,cdata,ivp,ivp); 974 padlock_xcrypt_ecb(1, cdata, ivp, ivp);
961 cdata->cword.b.encdec=1; 975 cdata->cword.b.encdec = 1;
962 padlock_reload_key(); 976 padlock_reload_key();
963 while(nbytes) { 977 while (nbytes) {
964 unsigned char c = *(in_arg++); 978 unsigned char c = *(in_arg++);
965 *(out_arg++) = c ^ *ivp; 979 *(out_arg++) = c ^ *ivp;
966 *(ivp++) = c, nbytes--; 980 *(ivp++) = c, nbytes--;
967 } 981 }
968 } 982 } else {
969 else { padlock_reload_key(); 983 padlock_reload_key();
970 padlock_xcrypt_ecb(1,cdata,ivp,ivp); 984 padlock_xcrypt_ecb(1, cdata, ivp, ivp);
971 padlock_reload_key(); 985 padlock_reload_key();
972 while (nbytes) { 986 while (nbytes) {
973 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp; 987 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
@@ -981,7 +995,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
981 995
982 case EVP_CIPH_OFB_MODE: 996 case EVP_CIPH_OFB_MODE:
983 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); 997 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
984 chunk &= ~(AES_BLOCK_SIZE-1); 998 chunk &= ~(AES_BLOCK_SIZE - 1);
985 if (chunk) do { 999 if (chunk) do {
986 if (inp_misaligned) 1000 if (inp_misaligned)
987 inp = padlock_memcpy(out, in_arg, chunk); 1001 inp = padlock_memcpy(out, in_arg, chunk);
@@ -989,15 +1003,17 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
989 inp = in_arg; 1003 inp = in_arg;
990 in_arg += chunk; 1004 in_arg += chunk;
991 1005
992 padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp); 1006 padlock_xcrypt_ofb(chunk / AES_BLOCK_SIZE, cdata,
1007 out, inp);
993 1008
994 if (out_misaligned) 1009 if (out_misaligned)
995 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; 1010 out_arg = padlock_memcpy(out_arg, out, chunk) +
1011 chunk;
996 else 1012 else
997 out = out_arg+=chunk; 1013 out = out_arg += chunk;
998 1014
999 nbytes -= chunk; 1015 nbytes -= chunk;
1000 chunk = PADLOCK_CHUNK; 1016 chunk = PADLOCK_CHUNK;
1001 } while (nbytes >= AES_BLOCK_SIZE); 1017 } while (nbytes >= AES_BLOCK_SIZE);
1002 1018
1003 if (nbytes) { 1019 if (nbytes) {
@@ -1005,7 +1021,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
1005 1021
1006 ctx->num = nbytes; 1022 ctx->num = nbytes;
1007 padlock_reload_key(); /* empirically found */ 1023 padlock_reload_key(); /* empirically found */
1008 padlock_xcrypt_ecb(1,cdata,ivp,ivp); 1024 padlock_xcrypt_ecb(1, cdata, ivp, ivp);
1009 padlock_reload_key(); /* empirically found */ 1025 padlock_reload_key(); /* empirically found */
1010 while (nbytes) { 1026 while (nbytes) {
1011 *(out_arg++) = *(in_arg++) ^ *ivp; 1027 *(out_arg++) = *(in_arg++) ^ *ivp;
@@ -1022,9 +1038,10 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
1022 1038
1023 /* Clean the realign buffer if it was used */ 1039 /* Clean the realign buffer if it was used */
1024 if (out_misaligned) { 1040 if (out_misaligned) {
1025 volatile unsigned long *p=(void *)out; 1041 volatile unsigned long *p = (void *)out;
1026 size_t n = allocated/sizeof(*p); 1042 size_t n = allocated/sizeof(*p);
1027 while (n--) *p++=0; 1043 while (n--)
1044 *p++ = 0;
1028 } 1045 }
1029 1046
1030 memset(cdata->iv, 0, AES_BLOCK_SIZE); 1047 memset(cdata->iv, 0, AES_BLOCK_SIZE);
@@ -1041,7 +1058,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
1041 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it 1058 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
1042 * provide meaningful error control... 1059 * provide meaningful error control...
1043 */ 1060 */
1044/* Wrapper that provides an interface between the API and 1061/* Wrapper that provides an interface between the API and
1045 the raw PadLock RNG */ 1062 the raw PadLock RNG */
1046static int 1063static int
1047padlock_rand_bytes(unsigned char *output, int count) 1064padlock_rand_bytes(unsigned char *output, int count)
@@ -1050,25 +1067,33 @@ padlock_rand_bytes(unsigned char *output, int count)
1050 1067
1051 while (count >= 8) { 1068 while (count >= 8) {
1052 eax = padlock_xstore(output, 0); 1069 eax = padlock_xstore(output, 0);
1053 if (!(eax&(1<<6))) return 0; /* RNG disabled */ 1070 if (!(eax & (1 << 6)))
1071 return 0; /* RNG disabled */
1054 /* this ---vv--- covers DC bias, Raw Bits and String Filter */ 1072 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1055 if (eax&(0x1F<<10)) return 0; 1073 if (eax & (0x1F << 10))
1056 if ((eax&0x1F)==0) continue; /* no data, retry... */ 1074 return 0;
1057 if ((eax&0x1F)!=8) return 0; /* fatal failure... */ 1075 if ((eax & 0x1F) == 0)
1076 continue; /* no data, retry... */
1077 if ((eax & 0x1F) != 8)
1078 return 0; /* fatal failure... */
1058 output += 8; 1079 output += 8;
1059 count -= 8; 1080 count -= 8;
1060 } 1081 }
1061 while (count > 0) { 1082 while (count > 0) {
1062 eax = padlock_xstore(&buf, 3); 1083 eax = padlock_xstore(&buf, 3);
1063 if (!(eax&(1<<6))) return 0; /* RNG disabled */ 1084 if (!(eax & (1 << 6)))
1085 return 0; /* RNG disabled */
1064 /* this ---vv--- covers DC bias, Raw Bits and String Filter */ 1086 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1065 if (eax&(0x1F<<10)) return 0; 1087 if (eax & (0x1F << 10))
1066 if ((eax&0x1F)==0) continue; /* no data, retry... */ 1088 return 0;
1067 if ((eax&0x1F)!=1) return 0; /* fatal failure... */ 1089 if ((eax & 0x1F) == 0)
1090 continue; /* no data, retry... */
1091 if ((eax & 0x1F) != 1)
1092 return 0; /* fatal failure... */
1068 *output++ = (unsigned char)buf; 1093 *output++ = (unsigned char)buf;
1069 count--; 1094 count--;
1070 } 1095 }
1071 *(volatile unsigned int *)&buf=0; 1096 *(volatile unsigned int *)&buf = 0;
1072 1097
1073 return 1; 1098 return 1;
1074} 1099}
@@ -1089,10 +1114,11 @@ static RAND_METHOD padlock_rand = {
1089 1114
1090#else /* !COMPILE_HW_PADLOCK */ 1115#else /* !COMPILE_HW_PADLOCK */
1091#ifndef OPENSSL_NO_DYNAMIC_ENGINE 1116#ifndef OPENSSL_NO_DYNAMIC_ENGINE
1092extern 1117extern int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
1093int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); 1118extern int
1094extern 1119bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) {
1095int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; } 1120 return 0;
1121}
1096IMPLEMENT_DYNAMIC_CHECK_FN() 1122IMPLEMENT_DYNAMIC_CHECK_FN()
1097#endif 1123#endif
1098#endif /* COMPILE_HW_PADLOCK */ 1124#endif /* COMPILE_HW_PADLOCK */