Home | History | Annotate | Download | only in crypto
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      6  * The implementation was written so as to conform with Netscapes SSL.
      7  *
      8  * This library is free for commercial and non-commercial use as long as
      9  * the following conditions are aheared to.  The following conditions
     10  * apply to all code found in this distribution, be it the RC4, RSA,
     11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     12  * included with this distribution is covered by the same copyright terms
     13  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     14  *
     15  * Copyright remains Eric Young's, and as such any Copyright notices in
     16  * the code are not to be removed.
     17  * If this package is used in a product, Eric Young should be given attribution
     18  * as the author of the parts of the library used.
     19  * This can be in the form of a textual message at program startup or
     20  * in documentation (online or textual) provided with the package.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  * 3. All advertising materials mentioning features or use of this software
     31  *    must display the following acknowledgement:
     32  *    "This product includes cryptographic software written by
     33  *     Eric Young (eay (at) cryptsoft.com)"
     34  *    The word 'cryptographic' can be left out if the rouines from the library
     35  *    being used are not cryptographic related :-).
     36  * 4. If you include any Windows specific code (or a derivative thereof) from
     37  *    the apps directory (application code) you must include an acknowledgement:
     38  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     50  * SUCH DAMAGE.
     51  *
     52  * The licence and distribution terms for any publically available version or
     53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     54  * copied and put under another distribution licence
     55  * [including the GNU Public Licence.] */
     56 
     57 #include <openssl/mem.h>
     58 
     59 #include <assert.h>
     60 #include <stdarg.h>
     61 #include <stdio.h>
     62 #include <string.h>
     63 
     64 #if defined(OPENSSL_WINDOWS)
     65 OPENSSL_MSVC_PRAGMA(warning(push, 3))
     66 #include <windows.h>
     67 OPENSSL_MSVC_PRAGMA(warning(pop))
     68 #else
     69 #include <strings.h>
     70 #endif
     71 
     72 #include "internal.h"
     73 
     74 
     75 #define OPENSSL_MALLOC_PREFIX 8
     76 
     77 
     78 void *OPENSSL_malloc(size_t size) {
     79   void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX);
     80   if (ptr == NULL) {
     81     return NULL;
     82   }
     83 
     84   *(size_t *)ptr = size;
     85 
     86   return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX;
     87 }
     88 
     89 void OPENSSL_free(void *orig_ptr) {
     90   if (orig_ptr == NULL) {
     91     return;
     92   }
     93 
     94   void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX;
     95 
     96   size_t size = *(size_t *)ptr;
     97   OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX);
     98   free(ptr);
     99 }
    100 
    101 void *OPENSSL_realloc(void *orig_ptr, size_t new_size) {
    102   if (orig_ptr == NULL) {
    103     return OPENSSL_malloc(new_size);
    104   }
    105 
    106   void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX;
    107   size_t old_size = *(size_t *)ptr;
    108 
    109   void *ret = OPENSSL_malloc(new_size);
    110   if (ret == NULL) {
    111     return NULL;
    112   }
    113 
    114   size_t to_copy = new_size;
    115   if (old_size < to_copy) {
    116     to_copy = old_size;
    117   }
    118 
    119   memcpy(ret, orig_ptr, to_copy);
    120   OPENSSL_free(orig_ptr);
    121 
    122   return ret;
    123 }
    124 
    125 void OPENSSL_cleanse(void *ptr, size_t len) {
    126 #if defined(OPENSSL_WINDOWS)
    127   SecureZeroMemory(ptr, len);
    128 #else
    129   OPENSSL_memset(ptr, 0, len);
    130 
    131 #if !defined(OPENSSL_NO_ASM)
    132   /* As best as we can tell, this is sufficient to break any optimisations that
    133      might try to eliminate "superfluous" memsets. If there's an easy way to
    134      detect memset_s, it would be better to use that. */
    135   __asm__ __volatile__("" : : "r"(ptr) : "memory");
    136 #endif
    137 #endif  // !OPENSSL_NO_ASM
    138 }
    139 
    140 int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) {
    141   const uint8_t *a = in_a;
    142   const uint8_t *b = in_b;
    143   uint8_t x = 0;
    144 
    145   for (size_t i = 0; i < len; i++) {
    146     x |= a[i] ^ b[i];
    147   }
    148 
    149   return x;
    150 }
    151 
    152 uint32_t OPENSSL_hash32(const void *ptr, size_t len) {
    153   // These are the FNV-1a parameters for 32 bits.
    154   static const uint32_t kPrime = 16777619u;
    155   static const uint32_t kOffsetBasis = 2166136261u;
    156 
    157   const uint8_t *in = ptr;
    158   uint32_t h = kOffsetBasis;
    159 
    160   for (size_t i = 0; i < len; i++) {
    161     h ^= in[i];
    162     h *= kPrime;
    163   }
    164 
    165   return h;
    166 }
    167 
    168 size_t OPENSSL_strnlen(const char *s, size_t len) {
    169   for (size_t i = 0; i < len; i++) {
    170     if (s[i] == 0) {
    171       return i;
    172     }
    173   }
    174 
    175   return len;
    176 }
    177 
    178 char *OPENSSL_strdup(const char *s) {
    179   const size_t len = strlen(s) + 1;
    180   char *ret = OPENSSL_malloc(len);
    181   if (ret == NULL) {
    182     return NULL;
    183   }
    184   OPENSSL_memcpy(ret, s, len);
    185   return ret;
    186 }
    187 
    188 int OPENSSL_tolower(int c) {
    189   if (c >= 'A' && c <= 'Z') {
    190     return c + ('a' - 'A');
    191   }
    192   return c;
    193 }
    194 
    195 int OPENSSL_strcasecmp(const char *a, const char *b) {
    196   for (size_t i = 0;; i++) {
    197     const int aa = OPENSSL_tolower(a[i]);
    198     const int bb = OPENSSL_tolower(b[i]);
    199 
    200     if (aa < bb) {
    201       return -1;
    202     } else if (aa > bb) {
    203       return 1;
    204     } else if (aa == 0) {
    205       return 0;
    206     }
    207   }
    208 }
    209 
    210 int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
    211   for (size_t i = 0; i < n; i++) {
    212     const int aa = OPENSSL_tolower(a[i]);
    213     const int bb = OPENSSL_tolower(b[i]);
    214 
    215     if (aa < bb) {
    216       return -1;
    217     } else if (aa > bb) {
    218       return 1;
    219     } else if (aa == 0) {
    220       return 0;
    221     }
    222   }
    223 
    224   return 0;
    225 }
    226 
    227 int BIO_snprintf(char *buf, size_t n, const char *format, ...) {
    228   va_list args;
    229   va_start(args, format);
    230   int ret = BIO_vsnprintf(buf, n, format, args);
    231   va_end(args);
    232   return ret;
    233 }
    234 
    235 int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) {
    236   return vsnprintf(buf, n, format, args);
    237 }
    238