[openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
0.9.8o and 1.0.0a are not binary compatible. And they're very old anyway :) Closing ticket. -- Rich Salz, OpenSSL dev team; rs...@openssl.org __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
My apologies for my ignorance in misunderstanding where you were going on 1.0, compatibility-wise. It all seemed so close... Indeed, the 1.0 EVP_MD_CTX size change already bit me, but only because I had embedded the struct in one of my structs, bad coding anyway. If I let the DLL allocate the memory, i.e, EVP_MD_CTX_create)(), that part worked. My application uses a limited number of ciphers and digests, and my access to them is primarily function-based, with little or no playing around with the structs. So, I may still pursue my attempt at writing OpenSSL major version independent code. Thank you for all your help, JGS - Original Message - From: "Mounir IDRASSI" To: Cc: "John Skodon" Sent: Wednesday, July 28, 2010 6:21 PM Subject: Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium Hi, I mentioned only the low-level APIs because at the time of my writing I remembered only these. Actually, there are also breaking changes in high-level APIs between the 0.9.8 and the 1.0 series. For example, if you look at the EVP high-level API, you'll notice that new fields have been added to the EVP_PKEY and EVP_MD structures and that the *do_cipher* callback in the EVP_CIPHER structure had its last parameter type changed from unsigned int to size_t. Also, in the SSL API, the structure SSL_CIPHER saw many fields removed and new ones added. These changed, especially the different structures modified definitions, were in most cases needed to accommodate new features that couldn't be supported using the older defines. So, as Steve said in a previous posting, "OpenSSL doesn't claim binary compatibility across major version changes: in general recompiling source against different major versions is recommended". And I will add that in many cases, recompiling is mandatory. I hope this clarifies things. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/29/2010 12:19 AM, John Skodon wrote: Hi: Thanks for the quick reply. You mentioned "...not meant to be binary compatible...for low-level APIs..". However, it could have been binary compatible had the size_t version of the function been given a new name, e.g., AES_ctr128_encrypt_sz(), while the old entry name had also been retained for the "unsigned long" version. If you're using GetProcAddress() to retrieve the function address out of the DLL, you've got to decide, based on SSL version, which function pointer var to associate with the func and which to use, on the fly. A bit tricky, perhaps. With C, you can't have two different prototypes for the same function, not to mention, how would you call one versus another? Anyway, it's probably too late now, even if I could persuade you to change. There would still be some tricky func var switching required for versions 1.0.0, and 1.0.0a. Also, I haven't diff-ed all the function protos in SSL. So, you're saying you didn't do any "unsigned long" to "size_t" changes in the higher-level prototypes? JGS - Original Message - From: "Mounir IDRASSI via RT" To: Cc: Sent: Wednesday, July 28, 2010 8:03 AM Subject: Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium Hi, As far as I know, OpenSSL 1.0 is not meant to be binary compatible with OpenSSL 0.9.8x, at least for low-level APIs like the AES one you are referring to. So, as you suggest it, an application should know if it is using a 0.9.8 libeay32 or an 1.0 one, and depending on that it will use the correct prototype. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/28/2010 3:02 PM, John Skodon via RT wrote: Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a pr
Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
Hi, I mentioned only the low-level APIs because at the time of my writing I remembered only these. Actually, there are also breaking changes in high-level APIs between the 0.9.8 and the 1.0 series. For example, if you look at the EVP high-level API, you'll notice that new fields have been added to the EVP_PKEY and EVP_MD structures and that the *do_cipher* callback in the EVP_CIPHER structure had its last parameter type changed from unsigned int to size_t. Also, in the SSL API, the structure SSL_CIPHER saw many fields removed and new ones added. These changed, especially the different structures modified definitions, were in most cases needed to accommodate new features that couldn't be supported using the older defines. So, as Steve said in a previous posting, "OpenSSL doesn't claim binary compatibility across major version changes: in general recompiling source against different major versions is recommended". And I will add that in many cases, recompiling is mandatory. I hope this clarifies things. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/29/2010 12:19 AM, John Skodon wrote: Hi: Thanks for the quick reply. You mentioned "...not meant to be binary compatible...for low-level APIs..". However, it could have been binary compatible had the size_t version of the function been given a new name, e.g., AES_ctr128_encrypt_sz(), while the old entry name had also been retained for the "unsigned long" version. If you're using GetProcAddress() to retrieve the function address out of the DLL, you've got to decide, based on SSL version, which function pointer var to associate with the func and which to use, on the fly. A bit tricky, perhaps. With C, you can't have two different prototypes for the same function, not to mention, how would you call one versus another? Anyway, it's probably too late now, even if I could persuade you to change. There would still be some tricky func var switching required for versions 1.0.0, and 1.0.0a. Also, I haven't diff-ed all the function protos in SSL. So, you're saying you didn't do any "unsigned long" to "size_t" changes in the higher-level prototypes? JGS - Original Message ----- From: "Mounir IDRASSI via RT" To: Cc: Sent: Wednesday, July 28, 2010 8:03 AM Subject: Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium Hi, As far as I know, OpenSSL 1.0 is not meant to be binary compatible with OpenSSL 0.9.8x, at least for low-level APIs like the AES one you are referring to. So, as you suggest it, an application should know if it is using a 0.9.8 libeay32 or an 1.0 one, and depending on that it will use the correct prototype. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/28/2010 3:02 PM, John Skodon via RT wrote: Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, * size_t length*, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, * const unsigned long length*, const AES_KEY *key, unsigned char ivec[AES_BL
Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
Hi: Thanks for the quick reply. You mentioned "...not meant to be binary compatible...for low-level APIs..". However, it could have been binary compatible had the size_t version of the function been given a new name, e.g., AES_ctr128_encrypt_sz(), while the old entry name had also been retained for the "unsigned long" version. If you're using GetProcAddress() to retrieve the function address out of the DLL, you've got to decide, based on SSL version, which function pointer var to associate with the func and which to use, on the fly. A bit tricky, perhaps. With C, you can't have two different prototypes for the same function, not to mention, how would you call one versus another? Anyway, it's probably too late now, even if I could persuade you to change. There would still be some tricky func var switching required for versions 1.0.0, and 1.0.0a. Also, I haven't diff-ed all the function protos in SSL. So, you're saying you didn't do any "unsigned long" to "size_t" changes in the higher-level prototypes? JGS - Original Message - From: "Mounir IDRASSI via RT" To: Cc: Sent: Wednesday, July 28, 2010 8:03 AM Subject: Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium Hi, As far as I know, OpenSSL 1.0 is not meant to be binary compatible with OpenSSL 0.9.8x, at least for low-level APIs like the AES one you are referring to. So, as you suggest it, an application should know if it is using a 0.9.8 libeay32 or an 1.0 one, and depending on that it will use the correct prototype. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/28/2010 3:02 PM, John Skodon via RT wrote: Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, * size_t length*, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, * const unsigned long length*, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
Hi, As far as I know, OpenSSL 1.0 is not meant to be binary compatible with OpenSSL 0.9.8x, at least for low-level APIs like the AES one you are referring to. So, as you suggest it, an application should know if it is using a 0.9.8 libeay32 or an 1.0 one, and depending on that it will use the correct prototype. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/28/2010 3:02 PM, John Skodon via RT wrote: > Hi guys: > > I'm probably wrong here, but it looks like you've changed some function > prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" > in 0.9.8o. > > E.g., > 0.9.8o, AES.H: > void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, > size_t length, const AES_KEY *key, > unsigned char ivec[AES_BLOCK_SIZE], > unsigned char ecount_buf[AES_BLOCK_SIZE], > unsigned int *num); > > 1.0.0a, AES.H: > void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, > const unsigned long length, const AES_KEY *key, > unsigned char ivec[AES_BLOCK_SIZE], > unsigned char ecount_buf[AES_BLOCK_SIZE], > unsigned int *num); > > The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" > and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem > that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push > 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. > > Just about every other popular compiler model I can think of, primarily W32, > Unix 32, and Unix 64 LP64 would not experience a problem. > > If I'm correct, code calling these functions on AMD/x64 would need maybe two > different function pointers defined for AES_ctr128_encrypt(), and on the fly > switching between the two, depending on the version retrieved from > LIBEAY32.DLL. > > Am I missing something here? > > Thanks in advance for your help, > JGS > > > > Hi guys: > I'm probably wrong here, but it looks like you've changed some function > prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in > 0.9.8o. > E.g., > 0.9.8o, AES.H: > void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, > * size_t length*, const AES_KEY *key, > unsigned char ivec[AES_BLOCK_SIZE], > unsigned char ecount_buf[AES_BLOCK_SIZE], > unsigned int *num); > 1.0.0a, AES.H: > void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, > * const unsigned long length*, const AES_KEY *key, > unsigned char ivec[AES_BLOCK_SIZE], > unsigned char ecount_buf[AES_BLOCK_SIZE], > unsigned int *num); > The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" > and > "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that > code > that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less > onto the stack on AMD/Itanium than code using the 1.0.0a headers. > Just about every other popular compiler model I can think of, primarily W32, > Unix 32, and Unix 64 LP64 would not experience a problem. > If I'm correct, code calling these functions on AMD/x64 would need maybe two > different function pointers defined for AES_ctr128_encrypt(), and on the fly > switching between the two, depending on the version retrieved from > LIBEAY32.DLL. > Am I missing something here? > Thanks in advance for your help, > JGS __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: [openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
Hi, As far as I know, OpenSSL 1.0 is not meant to be binary compatible with OpenSSL 0.9.8x, at least for low-level APIs like the AES one you are referring to. So, as you suggest it, an application should know if it is using a 0.9.8 libeay32 or an 1.0 one, and depending on that it will use the correct prototype. Cheers, -- Mounir IDRASSI IDRIX http://www.idrix.fr On 7/28/2010 3:02 PM, John Skodon via RT wrote: Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, * size_t length*, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, * const unsigned long length*, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
[openssl.org #2312] Function protos in 1.0.0a: unsigned long changed to size_t not so good for amd/x64, Itanium
Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS Hi guys: I'm probably wrong here, but it looks like you've changed some function prototypes, e.g., aes.h, in version 1.0.0a to "size_t" from "unsigned long" in 0.9.8o. E.g., 0.9.8o, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); 1.0.0a, AES.H: void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num); The eccentric LLP64 model of Microsoft Windows AMD64 and Itanium has "long" and "unsigned long" as 32-bits, and "size_t" as 64-bits. So, it would seem that code that called AES_ctr128_encrypt() compiled under 0.9.8o would push 32-bits less onto the stack on AMD/Itanium than code using the 1.0.0a headers. Just about every other popular compiler model I can think of, primarily W32, Unix 32, and Unix 64 LP64 would not experience a problem. If I'm correct, code calling these functions on AMD/x64 would need maybe two different function pointers defined for AES_ctr128_encrypt(), and on the fly switching between the two, depending on the version retrieved from LIBEAY32.DLL. Am I missing something here? Thanks in advance for your help, JGS