Hi, In CVS OPENSSL_1_0_1-stable branch, on a ILP32 target (where sizeof(long) == 4), the function OPENSSL_ia32cap_loc() is clearing upper bits of capability vector which disable support for SSE3, AES-NI, etc...
See http://www.openssl.org/docs/crypto/OPENSSL_ia32cap.html for more information. In crypto/crypto.h: unsigned long *OPENSSL_ia32cap_loc(void); #define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) In crypto/cryptlib.c: unsigned int OPENSSL_ia32cap_P[2]; unsigned long *OPENSSL_ia32cap_loc(void) { if (sizeof(long)==4) /* * If 32-bit application pulls address of OPENSSL_ia32cap_P[0] * clear second element to maintain the illusion that vector * is 32-bit. */ OPENSSL_ia32cap_P[1]=0; return (unsigned long *)OPENSSL_ia32cap_P; } A user program not reading/writing OPENSSL_ia32cap before using other encryption, decryption or digest functions would benefit from SSE3, AES-NI and such if available. But after calling the function, those support would be disabled. In CVS HEAD, the problem does not exist. OPENSSL_ia32cap_loc() returns a pointer to int instead of a pointer to long (this is an ABI change between 1.0.1 and HEAD), and doesn't clear upper bits. In crypto/crypto.h: unsigned int *OPENSSL_ia32cap_loc(void); #define OPENSSL_ia32cap ((OPENSSL_ia32cap_loc())[0]) In crypto/cryptlib.c: extern unsigned int OPENSSL_ia32cap_P[2]; unsigned int *OPENSSL_ia32cap_loc(void) { return OPENSSL_ia32cap_P; } The solution currently in HEAD is not perfect since it doesn't allow user program to read upper bits of the capability vector. Worse, it doesn't allow it to write upper bits of the vector, for example to disable some capabilities. I think that a better way to expose capabilities to user program would be an array and a count/length: In crypto/crypto.h: extern unsigned int *OPENSSL_ia32cap_loc(void); #define OPENSSL_ia32cap (OPENSSL_ia32cap_loc()) extern unsigned int OPENSSL_ia32cap_cnt(void); #define OPENSSL_ia32cap_cnt (OPENSSL_ia32cap_cnt()) In crypto/cryptlib.c: #define OPENSSL_ia32cap_CNT 2 extern unsigned int OPENSSL_ia32cap_P[OPENSSL_ia32cap_CNT]; unsigned int *OPENSSL_ia32cap_loc(void) { return OPENSSL_ia32cap_P; } unsigned int OPENSSL_ia32cap_cnt(void) { return OPENSSL_ia32cap_CNT; } Regards -- Yann Droneaud ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [email protected] Automated List Manager [email protected]
