The doc/crypto/OPENSSL_ia32cap.pod documentation at [http://www.openssl.org/docs/crypto/OPENSSL_ia32cap.html] defines the return of OPENSSL_ia32cap_loc() as a pointer to a (32-bit) integer with a feature (AES Instr.) available if bit 57 is set.
Before 2009/09/13 /crypto/cryptlib.c did define this location as "unsigned long OPENSSL_ia32cap_P" (32-bit on x86). Since 2009/09/13, /crypto/cryptlib.c defines it as a 2x 32-bit "unsigned int OPENSSL_ia32cap_P[2];". It should be clarified in the documentation that the returned value now is an address of two variables with EDX at [0] and ECX at [1]. This new behavior is not backward compatible with versions before 2009/09/13, because an application has no chance to check whether the second integer does exist. Solution suggestion: To circumvent this problem bit #10 in EDX could be used to signal that ECX at [1] exists. In the past this bit was always cleared. Referenced on Intel's documentation, this is the last, otherwise unused reserved bit. (#20 and #30 are already taken by OpenSSL.) [http://www.intel.com/Assets/PDF/appnote/241618.pdf] (page 22) So, versions returning two integers should be built in /crypto/cryptlib.c as: OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10)|(1<<9); OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32); instead of: OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10); OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32); With this little extension such a selection would be possible: unsigned int *p=OPENSSL_ia32cap_loc(); if((p[0] & 0x04000400) && (p[1] & 0x02000000)) {/* AES and SSE2 instructions available */} else if(p[0] & 0x04000000) {/* Only SSE2 instructions available */} else {/* Conventional solution */} Peter-Michael -- Peter-Michael Hager - HAGER-ELECTRONICS GmbH - Germany ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [email protected] Automated List Manager [email protected]
