74 #ifndef OPENSSL_NO_AES
81 #ifndef OPENSSL_NO_HW_PADLOCK
84 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
85 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
86 # define DYNAMIC_ENGINE
88 #elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
89 # ifdef ENGINE_DYNAMIC_SUPPORT
90 # define DYNAMIC_ENGINE
93 # error "Only OpenSSL >= 0.9.7 is supported"
102 #undef COMPILE_HW_PADLOCK
103 #if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
104 # if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
105 (defined(_MSC_VER) && defined(_M_IX86))
106 # define COMPILE_HW_PADLOCK
110 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
111 #ifdef COMPILE_HW_PADLOCK
112 static ENGINE *ENGINE_padlock (
void);
118 #ifdef COMPILE_HW_PADLOCK
119 ENGINE *toadd = ENGINE_padlock ();
129 #ifdef COMPILE_HW_PADLOCK
136 # define alloca _alloca
138 #elif defined(__GNUC__)
140 # define alloca(s) __builtin_alloca(s)
145 static int padlock_available(
void);
146 static int padlock_init(
ENGINE *
e);
152 #ifndef OPENSSL_NO_AES
157 static const char *padlock_id =
"padlock";
158 static char padlock_name[100];
161 static int padlock_use_ace = 0;
162 static int padlock_use_rng = 0;
163 #ifndef OPENSSL_NO_AES
164 static int padlock_aes_align_required = 1;
182 "VIA PadLock (%s, %s)",
183 padlock_use_rng ?
"RNG" :
"no-RNG",
184 padlock_use_ace ?
"ACE" :
"no-ACE");
191 #ifndef OPENSSL_NO_AES
202 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
214 if (!padlock_bind_helper(eng)) {
228 return (padlock_use_rng || padlock_use_ace);
234 #ifdef DYNAMIC_ENGINE
236 padlock_bind_fn(
ENGINE *e,
const char *
id)
238 if (
id && (strcmp(
id, padlock_id) != 0)) {
242 if (!padlock_bind_helper(e)) {
255 #ifndef OPENSSL_NO_AES
257 #define AES_BLOCK_SIZE 16
258 #define AES_KEY_SIZE_128 16
259 #define AES_KEY_SIZE_192 24
260 #define AES_KEY_SIZE_256 32
269 struct padlock_cipher_data
272 union {
unsigned int pad[4];
278 unsigned int keygen:1;
280 unsigned int encdec:1;
293 static volatile struct padlock_cipher_data *padlock_saved_context;
306 #if defined(__GNUC__) && __GNUC__>=2
317 padlock_insn_cpuid_available(
void)
326 "xorl $0x200000, %%eax\n"
327 "movl %%eax, %%ecx\n"
328 "andl $0x200000, %%ecx\n"
333 "andl $0x200000, %%eax\n"
334 "xorl %%eax, %%ecx\n"
336 :
"=r" (result) : :
"eax",
"ecx");
338 return (result == 0);
344 padlock_available(
void)
346 char vendor_string[16];
347 unsigned int eax, edx;
350 if (! padlock_insn_cpuid_available())
355 vendor_string[12] = 0;
359 "movl %%ebx,(%%edi)\n"
360 "movl %%edx,4(%%edi)\n"
361 "movl %%ecx,8(%%edi)\n"
363 :
"+a"(eax) :
"D"(vendor_string) :
"ecx",
"edx");
364 if (strcmp(vendor_string,
"CentaurHauls") != 0)
369 asm volatile (
"pushl %%ebx; cpuid; popl %%ebx"
370 :
"+a"(eax) : :
"ecx",
"edx");
371 if (eax < 0xC0000001)
376 asm volatile (
"pushl %%ebx; cpuid; popl %%ebx"
377 :
"+a"(eax),
"=d"(edx) : :
"ecx");
380 padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
381 padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
383 return padlock_use_ace + padlock_use_rng;
386 #ifndef OPENSSL_NO_AES
395 asm volatile (
"bswapl %0" :
"+r"(*key));
405 padlock_reload_key(
void)
407 asm volatile (
"pushfl; popfl");
410 #ifndef OPENSSL_NO_AES
421 padlock_verify_context(
struct padlock_cipher_data *cdata)
433 :
"+m"(padlock_saved_context)
434 :
"r"(padlock_saved_context),
"r"(cdata) :
"cc");
443 #define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
444 static inline void *name(size_t cnt, \
445 struct padlock_cipher_data *cdata, \
446 void *out, const void *inp) \
448 asm volatile ( "pushl %%ebx\n" \
449 " leal 16(%0),%%edx\n" \
450 " leal 32(%0),%%ebx\n" \
453 : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
454 : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
455 : "edx", "cc", "memory"); \
460 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,
".byte 0xf3,0x0f,0xa7,0xc8")
461 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".
byte 0xf3,0x0f,0xa7,0xd0")
462 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".
byte 0xf3,0x0f,0xa7,0xe0")
463 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".
byte 0xf3,0x0f,0xa7,0xe8")
467 static inline unsigned int
468 padlock_xstore(
void *addr,
unsigned int edx_in)
470 unsigned int eax_out;
472 asm volatile (
".byte 0x0f,0xa7,0xc0"
473 :
"=a"(eax_out),
"=m"(*(
unsigned *)addr)
474 :
"D"(addr),
"d" (edx_in)
491 static inline unsigned char *
492 padlock_memcpy(
void *dst,
const void *src,
size_t n)
498 do { *d++ = *s++; }
while (--n);
503 #elif defined(_MSC_VER)
511 #define REP_XCRYPT(code) \
513 _asm _emit 0x0f _asm _emit 0xa7 \
521 #define PADLOCK_XCRYPT_ASM(name,code) \
522 static void * __fastcall \
523 name (size_t cnt, void *cdata, \
524 void *outp, const void *inp) \
526 _asm lea edx,[eax+16] \
527 _asm lea ebx,[eax+32] \
533 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
534 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
535 PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
536 PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
538 static
int __fastcall
539 padlock_xstore(
void *outp,
unsigned int code)
541 _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
544 static void __fastcall
545 padlock_reload_key(
void)
546 { _asm pushfd _asm popfd }
548 static void __fastcall
549 padlock_verify_context(
void *cdata)
554 cmp ecx,padlock_saved_context
559 mov padlock_saved_context,ecx
564 padlock_available(
void)
599 mov padlock_use_ace,1
605 mov padlock_use_rng,1
612 static void __fastcall
613 padlock_bswapl(
void *key)
631 #define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
635 #ifndef OPENSSL_NO_AES
637 #if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
638 #define NID_aes_128_cfb NID_aes_128_cfb128
641 #if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
642 #define NID_aes_128_ofb NID_aes_128_ofb128
645 #if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
646 #define NID_aes_192_cfb NID_aes_192_cfb128
649 #if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
650 #define NID_aes_192_ofb NID_aes_192_ofb128
653 #if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
654 #define NID_aes_256_cfb NID_aes_256_cfb128
657 #if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
658 #define NID_aes_256_ofb NID_aes_256_ofb128
662 static int padlock_cipher_nids[] = {
678 static int padlock_cipher_nids_num = (
sizeof(padlock_cipher_nids)/
679 sizeof(padlock_cipher_nids[0]));
682 static int padlock_aes_init_key(
EVP_CIPHER_CTX *ctx,
const unsigned char *key,
683 const unsigned char *iv,
int enc);
684 static int padlock_aes_cipher(
EVP_CIPHER_CTX *ctx,
unsigned char *out,
685 const unsigned char *in,
size_t nbytes);
687 #define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
688 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
689 #define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
690 NEAREST_ALIGNED(ctx->cipher_data))
692 #define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
693 #define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
694 #define EVP_CIPHER_block_size_OFB 1
695 #define EVP_CIPHER_block_size_CFB 1
699 #define DECLARE_AES_EVP(ksize,lmode,umode) \
700 static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
701 NID_aes_##ksize##_##lmode, \
702 EVP_CIPHER_block_size_##umode, \
703 AES_KEY_SIZE_##ksize, \
705 0 | EVP_CIPH_##umode##_MODE, \
706 padlock_aes_init_key, \
707 padlock_aes_cipher, \
709 sizeof(struct padlock_cipher_data) + 16, \
710 EVP_CIPHER_set_asn1_iv, \
711 EVP_CIPHER_get_asn1_iv, \
716 DECLARE_AES_EVP(128,ecb,
ECB);
717 DECLARE_AES_EVP(128,cbc,
CBC);
718 DECLARE_AES_EVP(128,cfb,CFB);
719 DECLARE_AES_EVP(128,ofb,OFB);
721 DECLARE_AES_EVP(192,ecb,
ECB);
722 DECLARE_AES_EVP(192,cbc,
CBC);
723 DECLARE_AES_EVP(192,cfb,CFB);
724 DECLARE_AES_EVP(192,ofb,OFB);
726 DECLARE_AES_EVP(256,ecb,
ECB);
727 DECLARE_AES_EVP(256,cbc,
CBC);
728 DECLARE_AES_EVP(256,cfb,CFB);
729 DECLARE_AES_EVP(256,ofb,OFB);
736 *nids = padlock_cipher_nids;
737 return padlock_cipher_nids_num;
743 *cipher = &padlock_aes_128_ecb;
746 *cipher = &padlock_aes_128_cbc;
748 case NID_aes_128_cfb:
749 *cipher = &padlock_aes_128_cfb;
751 case NID_aes_128_ofb:
752 *cipher = &padlock_aes_128_ofb;
756 *cipher = &padlock_aes_192_ecb;
759 *cipher = &padlock_aes_192_cbc;
761 case NID_aes_192_cfb:
762 *cipher = &padlock_aes_192_cfb;
764 case NID_aes_192_ofb:
765 *cipher = &padlock_aes_192_ofb;
769 *cipher = &padlock_aes_256_ecb;
772 *cipher = &padlock_aes_256_cbc;
774 case NID_aes_256_cfb:
775 *cipher = &padlock_aes_256_cfb;
777 case NID_aes_256_ofb:
778 *cipher = &padlock_aes_256_ofb;
792 padlock_aes_init_key (
EVP_CIPHER_CTX *ctx,
const unsigned char *key,
793 const unsigned char *iv,
int enc)
795 struct padlock_cipher_data *cdata;
798 if (key==NULL)
return 0;
800 cdata = ALIGNED_CIPHER_DATA(ctx);
801 memset(cdata, 0,
sizeof(
struct padlock_cipher_data));
805 cdata->cword.b.encdec = 0;
807 cdata->cword.b.encdec = (ctx->
encrypt == 0);
808 cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
809 cdata->cword.b.ksize = (key_len - 128) / 64;
815 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
816 cdata->cword.b.keygen = 0;
835 padlock_bswapl(&cdata->ks);
837 cdata->cword.b.keygen = 1;
850 padlock_reload_key ();
862 padlock_aes_cipher_omnivorous(
EVP_CIPHER_CTX *ctx,
unsigned char *out_arg,
863 const unsigned char *in_arg,
size_t nbytes)
865 struct padlock_cipher_data *cdata;
868 cdata = ALIGNED_CIPHER_DATA(ctx);
869 padlock_verify_context(cdata);
873 padlock_xcrypt_ecb(nbytes/
AES_BLOCK_SIZE, cdata, out_arg, in_arg);
878 iv = padlock_xcrypt_cbc(nbytes/
AES_BLOCK_SIZE, cdata, out_arg, in_arg);
884 iv = padlock_xcrypt_cfb(nbytes/
AES_BLOCK_SIZE, cdata, out_arg, in_arg);
890 padlock_xcrypt_ofb(nbytes/
AES_BLOCK_SIZE, cdata, out_arg, in_arg);
903 #ifndef PADLOCK_CHUNK
904 # define PADLOCK_CHUNK 512
906 #if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
907 # error "insane PADLOCK_CHUNK..."
914 const unsigned char *in_arg,
size_t nbytes)
916 struct padlock_cipher_data *cdata;
920 int inp_misaligned, out_misaligned, realign_in_loop;
921 size_t chunk, allocated=0;
925 if ((chunk = ctx->
num)) {
926 unsigned char *ivp=ctx->
iv;
935 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
939 unsigned char c = *(in_arg++);
940 *(out_arg++) = c ^ ivp[chunk];
941 ivp[chunk++] = c, nbytes--;
951 *(out_arg++) = *(in_arg++) ^ ivp[chunk];
979 if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
980 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
982 inp_misaligned = (((size_t)in_arg) & 0x0F);
983 out_misaligned = (((size_t)out_arg) & 0x0F);
989 realign_in_loop = out_misaligned|inp_misaligned;
991 if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
992 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
996 chunk %= PADLOCK_CHUNK;
997 if (chunk==0) chunk = PADLOCK_CHUNK;
999 if (out_misaligned) {
1001 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
1002 out = alloca(0x10 + allocated);
1003 out = NEAREST_ALIGNED(out);
1008 cdata = ALIGNED_CIPHER_DATA(ctx);
1009 padlock_verify_context(cdata);
1015 inp = padlock_memcpy(out, in_arg, chunk);
1020 padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1023 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1025 out = out_arg+=chunk;
1028 chunk = PADLOCK_CHUNK;
1033 memcpy(cdata->iv, ctx->
iv, AES_BLOCK_SIZE);
1036 if (iv != cdata->iv)
1037 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1038 chunk = PADLOCK_CHUNK;
1041 inp = padlock_memcpy(out, in_arg, chunk);
1046 iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1049 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1051 out = out_arg+=chunk;
1053 }
while (nbytes -= chunk);
1054 memcpy(ctx->
iv, iv, AES_BLOCK_SIZE);
1058 memcpy (iv = cdata->iv, ctx->
iv, AES_BLOCK_SIZE);
1059 chunk &= ~(AES_BLOCK_SIZE-1);
1060 if (chunk)
goto cfb_shortcut;
1061 else goto cfb_skiploop;
1063 if (iv != cdata->iv)
1064 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1065 chunk = PADLOCK_CHUNK;
1068 inp = padlock_memcpy(out, in_arg, chunk);
1073 iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1076 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1078 out = out_arg+=chunk;
1081 }
while (nbytes >= AES_BLOCK_SIZE);
1085 unsigned char *ivp = cdata->iv;
1088 memcpy(ivp, iv, AES_BLOCK_SIZE);
1092 if (cdata->cword.b.encdec) {
1093 cdata->cword.b.encdec=0;
1094 padlock_reload_key();
1095 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1096 cdata->cword.b.encdec=1;
1097 padlock_reload_key();
1099 unsigned char c = *(in_arg++);
1100 *(out_arg++) = c ^ *ivp;
1101 *(ivp++) = c, nbytes--;
1104 else { padlock_reload_key();
1105 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1106 padlock_reload_key();
1108 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
1114 memcpy(ctx->
iv, iv, AES_BLOCK_SIZE);
1118 memcpy(cdata->iv, ctx->
iv, AES_BLOCK_SIZE);
1119 chunk &= ~(AES_BLOCK_SIZE-1);
1122 inp = padlock_memcpy(out, in_arg, chunk);
1127 padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1130 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1132 out = out_arg+=chunk;
1135 chunk = PADLOCK_CHUNK;
1136 }
while (nbytes >= AES_BLOCK_SIZE);
1139 unsigned char *ivp = cdata->iv;
1142 padlock_reload_key();
1143 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1144 padlock_reload_key();
1146 *(out_arg++) = *(in_arg++) ^ *ivp;
1151 memcpy(ctx->
iv, cdata->iv, AES_BLOCK_SIZE);
1159 if (out_misaligned) {
1160 volatile unsigned long *
p=(
void *)out;
1161 size_t n = allocated/
sizeof(*p);
1165 memset(cdata->iv, 0, AES_BLOCK_SIZE);
1182 padlock_rand_bytes(
unsigned char *output,
int count)
1184 unsigned int eax, buf;
1186 while (count >= 8) {
1187 eax = padlock_xstore(output, 0);
1188 if (!(eax&(1<<6)))
return 0;
1190 if (eax&(0x1F<<10))
return 0;
1191 if ((eax&0x1F)==0)
continue;
1192 if ((eax&0x1F)!=8)
return 0;
1197 eax = padlock_xstore(&buf, 3);
1198 if (!(eax&(1<<6)))
return 0;
1200 if (eax&(0x1F<<10))
return 0;
1201 if ((eax&0x1F)==0)
continue;
1202 if ((eax&0x1F)!=1)
return 0;
1203 *output++ = (
unsigned char)buf;
1206 *(
volatile unsigned int *)&buf=0;
1213 padlock_rand_status(
void)
1225 padlock_rand_status,
1229 #ifndef OPENSSL_NO_DYNAMIC_ENGINE