Work around language and compiler bug in memcpy, etc.

Most C standard library functions are undefined if passed NULL, even
when the corresponding length is zero. This gives them (and, in turn,
all functions which call them) surprising behavior on empty arrays.
Some compilers will miscompile code due to this rule. See also
https://www.imperialviolet.org/2016/06/26/nonnull.html

Add OPENSSL_memcpy, etc., wrappers which avoid this problem.

BUG=23

Change-Id: I95f42b23e92945af0e681264fffaf578e7f8465e
Reviewed-on: https://boringssl-review.googlesource.com/12928
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c
index 2705ea5..ea9da24 100644
--- a/crypto/asn1/a_bitstr.c
+++ b/crypto/asn1/a_bitstr.c
@@ -61,6 +61,9 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
 {
     return M_ASN1_BIT_STRING_set(x, d, len);
@@ -115,7 +118,7 @@
 
     *(p++) = (unsigned char)bits;
     d = a->data;
-    memcpy(p, d, len);
+    OPENSSL_memcpy(p, d, len);
     p += len;
     if (len > 0)
         p[-1] &= (0xff << bits);
@@ -162,7 +165,7 @@
             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
             goto err;
         }
-        memcpy(s, p, (int)len);
+        OPENSSL_memcpy(s, p, (int)len);
         s[len - 1] &= (0xff << padding);
         p += len;
     } else
@@ -215,7 +218,7 @@
             return 0;
         }
         if (w + 1 - a->length > 0)
-            memset(c + a->length, 0, w + 1 - a->length);
+            OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
         a->data = c;
         a->length = w + 1;
     }
diff --git a/crypto/asn1/a_enum.c b/crypto/asn1/a_enum.c
index 0b95fc9..cc46905 100644
--- a/crypto/asn1/a_enum.c
+++ b/crypto/asn1/a_enum.c
@@ -61,6 +61,9 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 /*
  * Code for ENUMERATED type: identical to INTEGER apart from a different tag.
  * for comments on encoding see a_int.c
@@ -79,7 +82,7 @@
             OPENSSL_free(a->data);
         if ((a->data =
              (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
-            memset((char *)a->data, 0, sizeof(long) + 1);
+            OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
     }
     if (a->data == NULL) {
         OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c
index 38a01bc..617ba96 100644
--- a/crypto/asn1/a_int.c
+++ b/crypto/asn1/a_int.c
@@ -61,6 +61,9 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
 {
     return M_ASN1_INTEGER_dup(x);
@@ -157,7 +160,7 @@
     if (a->length == 0)
         *(p++) = 0;
     else if (!neg)
-        memcpy(p, a->data, (unsigned int)a->length);
+        OPENSSL_memcpy(p, a->data, (unsigned int)a->length);
     else {
         /* Begin at the end of the encoding */
         n = a->data + a->length - 1;
@@ -254,7 +257,7 @@
             p++;
             len--;
         }
-        memcpy(s, p, (int)len);
+        OPENSSL_memcpy(s, p, (int)len);
     }
 
     if (ret->data != NULL)
@@ -322,7 +325,7 @@
             p++;
             len--;
         }
-        memcpy(s, p, (int)len);
+        OPENSSL_memcpy(s, p, (int)len);
         p += len;
     }
 
@@ -354,7 +357,7 @@
             OPENSSL_free(a->data);
         if ((a->data =
              (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
-            memset((char *)a->data, 0, sizeof(long) + 1);
+            OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1);
     }
     if (a->data == NULL) {
         OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
index fef9b79..a710add 100644
--- a/crypto/asn1/a_object.c
+++ b/crypto/asn1/a_object.c
@@ -63,6 +63,9 @@
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
+#include "../internal.h"
+
+
 int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
 {
     unsigned char *p;
@@ -77,7 +80,7 @@
 
     p = *pp;
     ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
-    memcpy(p, a->data, a->length);
+    OPENSSL_memcpy(p, a->data, a->length);
     p += a->length;
 
     *pp = p;
@@ -321,7 +324,7 @@
         }
         ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     }
-    memcpy(data, p, length);
+    OPENSSL_memcpy(data, p, length);
     /* reattach data to object, after which it remains const */
     ret->data = data;
     ret->length = length;
diff --git a/crypto/asn1/a_utctm.c b/crypto/asn1/a_utctm.c
index db5cd29..3b9d257 100644
--- a/crypto/asn1/a_utctm.c
+++ b/crypto/asn1/a_utctm.c
@@ -270,7 +270,7 @@
     struct tm tm;
     int offset;
 
-    memset(&tm, '\0', sizeof tm);
+    OPENSSL_memset(&tm, '\0', sizeof tm);
 
 # define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
     tm.tm_year = g2(s->data);
diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c
index 94553b1..774f151 100644
--- a/crypto/asn1/asn1_lib.c
+++ b/crypto/asn1/asn1_lib.c
@@ -63,6 +63,9 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 /* Cross-module errors from crypto/x509/i2d_pr.c. */
 OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE)
 
@@ -401,7 +404,7 @@
     }
     str->length = len;
     if (data != NULL) {
-        memcpy(str->data, data, len);
+        OPENSSL_memcpy(str->data, data, len);
         /* an allowance for strings :-) */
         str->data[len] = '\0';
     }
@@ -452,7 +455,7 @@
 
     i = (a->length - b->length);
     if (i == 0) {
-        i = memcmp(a->data, b->data, a->length);
+        i = OPENSSL_memcmp(a->data, b->data, a->length);
         if (i == 0)
             return (a->type - b->type);
         else
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index dfbd222..40778a8 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -1108,7 +1108,7 @@
             OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
             return 0;
         }
-        memcpy(buf->data + len, *p, plen);
+        OPENSSL_memcpy(buf->data + len, *p, plen);
     }
     *p += plen;
     return 1;
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index 7c2b365..9286ef6 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -62,6 +62,9 @@
 #include <openssl/asn1t.h>
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
                                  const ASN1_ITEM *it, int tag, int aclass);
 static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
@@ -415,7 +418,7 @@
     const DER_ENC *d1 = a, *d2 = b;
     int cmplen, i;
     cmplen = (d1->length < d2->length) ? d1->length : d2->length;
-    i = memcmp(d1->data, d2->data, cmplen);
+    i = OPENSSL_memcmp(d1->data, d2->data, cmplen);
     if (i)
         return i;
     return d1->length - d2->length;
@@ -470,7 +473,7 @@
     /* Output sorted DER encoding */
     p = *out;
     for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
-        memcpy(p, tder->data, tder->length);
+        OPENSSL_memcpy(p, tder->data, tder->length);
         p += tder->length;
     }
     *out = p;
@@ -660,6 +663,6 @@
 
     }
     if (cout && len)
-        memcpy(cout, cont, len);
+        OPENSSL_memcpy(cout, cont, len);
     return len;
 }
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 232fe46..053b732 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -63,6 +63,9 @@
 #include <openssl/mem.h>
 #include <openssl/obj.h>
 
+#include "../internal.h"
+
+
 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
                                     int combine);
 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
@@ -153,7 +156,7 @@
             *pval = OPENSSL_malloc(it->size);
             if (!*pval)
                 goto memerr;
-            memset(*pval, 0, it->size);
+            OPENSSL_memset(*pval, 0, it->size);
         }
         asn1_set_choice_selector(pval, -1, it);
         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
@@ -178,7 +181,7 @@
             *pval = OPENSSL_malloc(it->size);
             if (!*pval)
                 goto memerr;
-            memset(*pval, 0, it->size);
+            OPENSSL_memset(*pval, 0, it->size);
             asn1_refcount_set_one(pval, it);
             asn1_enc_init(pval, it);
         }
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index 3f53072..a7516f6 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -178,7 +178,7 @@
     if (!enc->enc) {
       return 0;
     }
-    memcpy(enc->enc, in, inlen);
+    OPENSSL_memcpy(enc->enc, in, inlen);
   }
 
   enc->len = inlen;
@@ -195,7 +195,7 @@
     return 0;
   }
   if (out) {
-    memcpy(*out, enc->enc, enc->len);
+    OPENSSL_memcpy(*out, enc->enc, enc->len);
     *out += enc->len;
   }
   if (len) {
diff --git a/crypto/asn1/x_long.c b/crypto/asn1/x_long.c
index bc4d275..b53127a 100644
--- a/crypto/asn1/x_long.c
+++ b/crypto/asn1/x_long.c
@@ -63,6 +63,9 @@
 #include <openssl/err.h>
 #include <openssl/mem.h>
 
+#include "../internal.h"
+
+
 /*
  * Custom primitive type for long handling. This converts between an
  * ASN1_INTEGER and a long directly.
@@ -117,7 +120,7 @@
     char *cp = (char *)pval;
 
     /* use memcpy, because we may not be long aligned */
-    memcpy(&ltmp, cp, sizeof(long));
+    OPENSSL_memcpy(&ltmp, cp, sizeof(long));
 
     if (ltmp == it->size)
         return -1;
@@ -186,7 +189,7 @@
         OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
         return 0;
     }
-    memcpy(cp, &ltmp, sizeof(long));
+    OPENSSL_memcpy(cp, &ltmp, sizeof(long));
     return 1;
 }