Re: AW: [openssl.org #3312] OpenSSL :: crypto/mem.c without memset() calls?

2014-04-16 Thread David Jacobson

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?

2014-04-16 Thread Vladimir Zatsepin
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?

2014-04-16 Thread Peter Waltenberg
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?

2014-04-15 Thread stefan.n...@t-online.de
   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