Line data Source code
1 : /* 2 : * Copyright (C) 2014 Red Hat 3 : * 4 : * This file is part of GnuTLS. 5 : * 6 : * The GnuTLS is free software; you can redistribute it and/or 7 : * modify it under the terms of the GNU Lesser General Public License 8 : * as published by the Free Software Foundation; either version 2.1 of 9 : * the License, or (at your option) any later version. 10 : * 11 : * This library is distributed in the hope that it will be useful, but 12 : * WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 : * Lesser General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU Lesser General Public License 17 : * along with this program. If not, see <https://www.gnu.org/licenses/> 18 : * 19 : */ 20 : 21 : #include "gnutls_int.h" 22 : #include <string.h> 23 : 24 : /** 25 : * gnutls_memset: 26 : * @data: the memory to set 27 : * @c: the constant byte to fill the memory with 28 : * @size: the size of memory 29 : * 30 : * This function will operate similarly to memset(), but will 31 : * not be optimized out by the compiler. 32 : * 33 : * Since: 3.4.0 34 : **/ 35 2626080 : void gnutls_memset(void *data, int c, size_t size) 36 : { 37 2626080 : volatile unsigned volatile_zero; 38 2626080 : volatile char *vdata = (volatile char*)data; 39 : #ifdef HAVE_EXPLICIT_BZERO 40 2626080 : if (c == 0) { 41 2626080 : explicit_bzero(data, size); 42 2626080 : return; 43 : } 44 : #endif 45 1 : volatile_zero = 0; 46 : 47 : /* This is based on a nice trick for safe memset, 48 : * sent by David Jacobson in the openssl-dev mailing list. 49 : */ 50 : 51 1 : if (size > 0) { 52 1 : do { 53 1 : memset(data, c, size); 54 1 : } while(vdata[volatile_zero] != c); 55 : } 56 : } 57 : 58 : /** 59 : * gnutls_memcmp: 60 : * @s1: the first address to compare 61 : * @s2: the second address to compare 62 : * @n: the size of memory to compare 63 : * 64 : * This function will operate similarly to memcmp(), but will operate 65 : * on time that depends only on the size of the string. That is will 66 : * not return early if the strings don't match on the first byte. 67 : * 68 : * Returns: non zero on difference and zero if the buffers are identical. 69 : * 70 : * Since: 3.4.0 71 : **/ 72 2765320 : int gnutls_memcmp(const void *s1, const void *s2, size_t n) 73 : { 74 2765320 : unsigned i; 75 2765320 : unsigned status = 0; 76 2765320 : const uint8_t *_s1 = s1; 77 2765320 : const uint8_t *_s2 = s2; 78 : 79 44136500 : for (i=0;i<n;i++) { 80 41371100 : status |= (_s1[i] ^ _s2[i]); 81 : } 82 : 83 2765320 : return status; 84 : } 85 : 86 : #ifdef TEST_SAFE_MEMSET 87 : int main() 88 : { 89 : char x[64]; 90 : 91 : gnutls_memset(x, 0, sizeof(x)); 92 : 93 : return 0; 94 : 95 : } 96 : 97 : #endif