diff options
Diffstat (limited to 'src/lib/libcrypto/engine/eng_padlock.c')
-rw-r--r-- | src/lib/libcrypto/engine/eng_padlock.c | 496 |
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 | */ |
264 | struct padlock_cipher_data | 264 | struct 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. */ |
399 | static inline void | 399 | static inline void |
400 | padlock_reload_key(void) | 400 | padlock_reload_key(void) |
@@ -416,21 +416,21 @@ static inline void | |||
416 | padlock_verify_context(struct padlock_cipher_data *cdata) | 416 | padlock_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 | */ |
486 | static inline unsigned char * | 486 | static inline unsigned char * |
487 | padlock_memcpy(void *dst,const void *src,size_t n) | 487 | padlock_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 | }; |
543 | static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/ | 544 | static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/ |
544 | sizeof(padlock_cipher_nids[0])); | 545 | sizeof(padlock_cipher_nids[0])); |
545 | 546 | ||
546 | /* Function prototypes ... */ | 547 | /* Function prototypes ... */ |
547 | static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 548 | static 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); |
549 | static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 550 | static 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 | ||
581 | DECLARE_AES_EVP(128,ecb,ECB); | 582 | DECLARE_AES_EVP(128, ecb, ECB); |
582 | DECLARE_AES_EVP(128,cbc,CBC); | 583 | DECLARE_AES_EVP(128, cbc, CBC); |
583 | DECLARE_AES_EVP(128,cfb,CFB); | 584 | DECLARE_AES_EVP(128, cfb, CFB); |
584 | DECLARE_AES_EVP(128,ofb,OFB); | 585 | DECLARE_AES_EVP(128, ofb, OFB); |
585 | 586 | ||
586 | DECLARE_AES_EVP(192,ecb,ECB); | 587 | DECLARE_AES_EVP(192, ecb, ECB); |
587 | DECLARE_AES_EVP(192,cbc,CBC); | 588 | DECLARE_AES_EVP(192, cbc, CBC); |
588 | DECLARE_AES_EVP(192,cfb,CFB); | 589 | DECLARE_AES_EVP(192, cfb, CFB); |
589 | DECLARE_AES_EVP(192,ofb,OFB); | 590 | DECLARE_AES_EVP(192, ofb, OFB); |
590 | 591 | ||
591 | DECLARE_AES_EVP(256,ecb,ECB); | 592 | DECLARE_AES_EVP(256, ecb, ECB); |
592 | DECLARE_AES_EVP(256,cbc,CBC); | 593 | DECLARE_AES_EVP(256, cbc, CBC); |
593 | DECLARE_AES_EVP(256,cfb,CFB); | 594 | DECLARE_AES_EVP(256, cfb, CFB); |
594 | DECLARE_AES_EVP(256,ofb,OFB); | 595 | DECLARE_AES_EVP(256, ofb, OFB); |
595 | 596 | ||
596 | static int | 597 | static int |
597 | padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid) | 598 | padlock_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 */ |
656 | static int | 654 | static int |
657 | padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key, | 655 | padlock_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 | */ |
726 | static int | 725 | static int |
727 | padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, | 726 | padlock_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. */ |
777 | static int | 780 | static int |
778 | padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, | 781 | padlock_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: | 962 | cfb_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 */ |
1046 | static int | 1063 | static int |
1047 | padlock_rand_bytes(unsigned char *output, int count) | 1064 | padlock_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 |
1092 | extern | 1117 | extern int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); |
1093 | int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); | 1118 | extern int |
1094 | extern | 1119 | bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { |
1095 | int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; } | 1120 | return 0; |
1121 | } | ||
1096 | IMPLEMENT_DYNAMIC_CHECK_FN() | 1122 | IMPLEMENT_DYNAMIC_CHECK_FN() |
1097 | #endif | 1123 | #endif |
1098 | #endif /* COMPILE_HW_PADLOCK */ | 1124 | #endif /* COMPILE_HW_PADLOCK */ |