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 */ |
