Re: AW: [openssl.org #3312] OpenSSL :: crypto/mem.c without memset() calls?
On 4/15/14 10:33 AM, stefan.n...@t-online.de wrote: Hi, I have checked the current source code of 'crpyto/mem.c' and I'm a little bit suprised that no memset()-calls are made before the free_*() functions are entered. I think a zeroing of the previous used memory is a good solutions to beware for accessing old memory content. Leaving aside the problem that just zeroing the memory simply doesn't work (for a start into that discussion see e.g. http://bytes.com/topic/c/answers/660296-memset-free), there is OPENSSL_cleanse which does something similar (actually, it overwrites the memory with garbage, not just with zeros) in a way that works. Attempting to be faster at run time, this needs to be called explicitly, though (and it's called in a lot of places if you look into the source code). But it might in fact be a good idea to put that call simply in the free function and be done with it. With modern processors, the slowdown is probably hardly nocticeable anyway. Regards, Stefan __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org Here is a means of using memset so that it can't be optimized out. #include stdint.h #include string.h void * safe_memset(void *s, int c, size_t n) { if (n 0) { volatile unsigned volatile_zero = 0; volatile uint8_t *vs = (volatile uint8_t*)s; do { memset(s, c, n); } while (vs[volatile_zero] != (uint8_t)c); } return s; } Since vs points to a volatile, the load in the while clause actually has to be done. That forces the compiler to actually store c into at least the byte that is tested, in practice byte zero. But the fact that the index is volatile zero, and since it is volatile it could spontaneously change to anything, the compiler has to store c into all bytes. The key observation is that while you can't pass a volatile to memset (you get a warning and the volatile gets stripped away), you can use a volatile in a test that could go the wrong way if the memset were elided. Could you C language lawyers please check this out and make sure I've not made a mistake. Thank you, --David __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: AW: [openssl.org #3312] OpenSSL :: crypto/mem.c without memset() calls?
Hi, Personally I use this function void* secure_memset(void *ptr, unsigned char c, size_t size) { unsigned char *tmp = (unsigned char *) ptr; if(!tmp) return NULL; while(size 0) { *tmp++ = c; size--; } return ptr; } It is not too fast as memset(), but gives some guaranties that memory will be filled correctly. 2014-04-16 8:31 GMT+04:00 David Jacobson dmjacob...@sbcglobal.net: On 4/15/14 10:33 AM, stefan.n...@t-online.de wrote: Hi, I have checked the current source code of 'crpyto/mem.c' and I'm a little bit suprised that no memset()-calls are made before the free_*() functions are entered. I think a zeroing of the previous used memory is a good solutions to beware for accessing old memory content. Leaving aside the problem that just zeroing the memory simply doesn't work (for a start into that discussion see e.g. http://bytes.com/topic/c/answers/660296-memset-free), there is OPENSSL_cleanse which does something similar (actually, it overwrites the memory with garbage, not just with zeros) in a way that works. Attempting to be faster at run time, this needs to be called explicitly, though (and it's called in a lot of places if you look into the source code). But it might in fact be a good idea to put that call simply in the free function and be done with it. With modern processors, the slowdown is probably hardly nocticeable anyway. Regards, Stefan __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org Here is a means of using memset so that it can't be optimized out. #include stdint.h #include string.h void * safe_memset(void *s, int c, size_t n) { if (n 0) { volatile unsigned volatile_zero = 0; volatile uint8_t *vs = (volatile uint8_t*)s; do { memset(s, c, n); } while (vs[volatile_zero] != (uint8_t)c); } return s; } Since vs points to a volatile, the load in the while clause actually has to be done. That forces the compiler to actually store c into at least the byte that is tested, in practice byte zero. But the fact that the index is volatile zero, and since it is volatile it could spontaneously change to anything, the compiler has to store c into all bytes. The key observation is that while you can't pass a volatile to memset (you get a warning and the volatile gets stripped away), you can use a volatile in a test that could go the wrong way if the memset were elided. Could you C language lawyers please check this out and make sure I've not made a mistake. Thank you, --David __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
Re: AW: [openssl.org #3312] OpenSSL :: crypto/mem.c without memset() calls?
In fact, it doesn't. The memset() function called has to be unknown to the compiler (i.e. not builtin) and in another module, but even there, the linker could optimize it out. And yes, there have been linkers 'capable' of optimizing that call out. Personally, I blame OS/2 for most of these problems.I dealt with the tinfoilhattery in our usage by explicitly testing that all sensitive objects freed were in fact cleaned up before release. Since OpenSSL allows you to hook malloc/free calls those tests aren't as difficult to write as it seems.If a compiler we use does ever misbehave, I'll deal with it if and when the tests for 'erasure' fail - and be able to be sure I've 'fixed' the feature.Peter-owner-openssl-...@openssl.org wrote: -To: openssl-dev@openssl.orgFrom: Vladimir Zatsepin <vladimir.zatse...@gmail.com>Sent by: owner-openssl-...@openssl.orgDate: 04/16/2014 06:06PMSubject: Re: AW: [openssl.org #3312] OpenSSL :: crypto/mem.c without "memset()" calls?Hi,Personally I use this functionvoid* secure_memset(void *ptr, unsigned char c, size_t size){ unsigned char *tmp = (unsigned char *) ptr; if(!tmp) return NULL; while(size 0) { *tmp++ = c; size--; } return ptr; }It is not too fast as memset(), but gives some guaranties that memory will be filled correctly.2014-04-16 8:31 GMT+04:00 David Jacobson dmjacob...@sbcglobal.net: On 4/15/14 10:33 AM, stefan.n...@t-online.de wrote: Hi, I have "checked" the current source code of 'crpyto/mem.c' and I'm a little bit suprised that no memset()-calls are made before the free_*() functions are entered. I think a "zeroing" of the previous used memory is a good solutions to beware for accessing old memory content. Leaving aside the problem that just zeroing the memory simply doesn't work (for a start into that discussion see e.g. http://bytes.com/topic/c/answers/660296-memset-free), there is OPENSSL_cleanse which does something similar (actually, it overwrites the memory with "garbage", not just with zeros) in a way that works. Attempting to be faster at run time, this needs to be called explicitly, though (and it's called in a lot of places if you look into the source code). But it might in fact be a good idea to put that call simply in the free function and be done with it. With modern processors, the slowdown is probably hardly nocticeable anyway. Regards, Stefan __ OpenSSL Project http://www.openssl.org Development Mailing Listopenssl-dev@openssl.org Automated List Manager majord...@openssl.org Here is a means of using memset so that it can't be optimized out. #include stdint.h #include string.h void * safe_memset(void *s, int c, size_t n) { if (n 0) { volatile unsigned volatile_zero = 0; volatile uint8_t *vs = (volatile uint8_t*)s; do { memset(s, c, n); } while (vs[volatile_zero] != (uint8_t)c); } return s; } Since vs points to a volatile, the load in the while clause actually has to be done. That forces the compiler to actually store c into at least the byte that is tested, in practice byte zero. But the fact that the index is volatile zero, and since it is volatile it could spontaneously change to anything, the compiler has to store c into all bytes. The key observation is that while you can't pass a volatile to memset (you get a warning and the volatile gets stripped away), you can use a volatile in a test that could go the wrong way if the memset were elided. Could you C language lawyers please check this out and make sure I've not made a mistake. Thank you, --David __ OpenSSL Project http://www.openssl.org Development Mailing Listopenssl-dev@openssl.org Automated List Manager majord...@openssl.org __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org
AW: [openssl.org #3312] OpenSSL :: crypto/mem.c without memset() calls?
Hi, I have checked the current source code of 'crpyto/mem.c' and I'm a little bit suprised that no memset()-calls are made before the free_*() functions are entered. I think a zeroing of the previous used memory is a good solutions to beware for accessing old memory content. Leaving aside the problem that just zeroing the memory simply doesn't work (for a start into that discussion see e.g. http://bytes.com/topic/c/answers/660296-memset-free), there is OPENSSL_cleanse which does something similar (actually, it overwrites the memory with garbage, not just with zeros) in a way that works. Attempting to be faster at run time, this needs to be called explicitly, though (and it's called in a lot of places if you look into the source code). But it might in fact be a good idea to put that call simply in the free function and be done with it. With modern processors, the slowdown is probably hardly nocticeable anyway. Regards, Stefan __ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org