LCOV - code coverage report
Current view: top level - crypto - memneq.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 28 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Constant-time equality testing of memory regions.
       3             :  *
       4             :  * Authors:
       5             :  *
       6             :  *   James Yonan <james@openvpn.net>
       7             :  *   Daniel Borkmann <dborkman@redhat.com>
       8             :  *
       9             :  * This file is provided under a dual BSD/GPLv2 license.  When using or
      10             :  * redistributing this file, you may do so under either license.
      11             :  *
      12             :  * GPL LICENSE SUMMARY
      13             :  *
      14             :  * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
      15             :  *
      16             :  * This program is free software; you can redistribute it and/or modify
      17             :  * it under the terms of version 2 of the GNU General Public License as
      18             :  * published by the Free Software Foundation.
      19             :  *
      20             :  * This program is distributed in the hope that it will be useful, but
      21             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      22             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      23             :  * General Public License for more details.
      24             :  *
      25             :  * You should have received a copy of the GNU General Public License
      26             :  * along with this program; if not, write to the Free Software
      27             :  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
      28             :  * The full GNU General Public License is included in this distribution
      29             :  * in the file called LICENSE.GPL.
      30             :  *
      31             :  * BSD LICENSE
      32             :  *
      33             :  * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
      34             :  *
      35             :  * Redistribution and use in source and binary forms, with or without
      36             :  * modification, are permitted provided that the following conditions
      37             :  * are met:
      38             :  *
      39             :  *   * Redistributions of source code must retain the above copyright
      40             :  *     notice, this list of conditions and the following disclaimer.
      41             :  *   * Redistributions in binary form must reproduce the above copyright
      42             :  *     notice, this list of conditions and the following disclaimer in
      43             :  *     the documentation and/or other materials provided with the
      44             :  *     distribution.
      45             :  *   * Neither the name of OpenVPN Technologies nor the names of its
      46             :  *     contributors may be used to endorse or promote products derived
      47             :  *     from this software without specific prior written permission.
      48             :  *
      49             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      50             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      51             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      52             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      53             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      54             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      55             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      56             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      57             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      58             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      59             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      60             :  */
      61             : 
      62             : #include <crypto/algapi.h>
      63             : 
      64             : #ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
      65             : 
      66             : /* Generic path for arbitrary size */
      67             : static inline unsigned long
      68           0 : __crypto_memneq_generic(const void *a, const void *b, size_t size)
      69             : {
      70           0 :         unsigned long neq = 0;
      71             : 
      72             : #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
      73           0 :         while (size >= sizeof(unsigned long)) {
      74           0 :                 neq |= *(unsigned long *)a ^ *(unsigned long *)b;
      75           0 :                 OPTIMIZER_HIDE_VAR(neq);
      76           0 :                 a += sizeof(unsigned long);
      77           0 :                 b += sizeof(unsigned long);
      78           0 :                 size -= sizeof(unsigned long);
      79             :         }
      80             : #endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
      81           0 :         while (size > 0) {
      82           0 :                 neq |= *(unsigned char *)a ^ *(unsigned char *)b;
      83           0 :                 OPTIMIZER_HIDE_VAR(neq);
      84           0 :                 a += 1;
      85           0 :                 b += 1;
      86           0 :                 size -= 1;
      87             :         }
      88           0 :         return neq;
      89             : }
      90             : 
      91             : /* Loop-free fast-path for frequently used 16-byte size */
      92           0 : static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
      93             : {
      94           0 :         unsigned long neq = 0;
      95             : 
      96             : #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
      97           0 :         if (sizeof(unsigned long) == 8) {
      98           0 :                 neq |= *(unsigned long *)(a)   ^ *(unsigned long *)(b);
      99           0 :                 OPTIMIZER_HIDE_VAR(neq);
     100           0 :                 neq |= *(unsigned long *)(a+8) ^ *(unsigned long *)(b+8);
     101           0 :                 OPTIMIZER_HIDE_VAR(neq);
     102             :         } else if (sizeof(unsigned int) == 4) {
     103             :                 neq |= *(unsigned int *)(a)    ^ *(unsigned int *)(b);
     104             :                 OPTIMIZER_HIDE_VAR(neq);
     105             :                 neq |= *(unsigned int *)(a+4)  ^ *(unsigned int *)(b+4);
     106             :                 OPTIMIZER_HIDE_VAR(neq);
     107             :                 neq |= *(unsigned int *)(a+8)  ^ *(unsigned int *)(b+8);
     108             :                 OPTIMIZER_HIDE_VAR(neq);
     109             :                 neq |= *(unsigned int *)(a+12) ^ *(unsigned int *)(b+12);
     110             :                 OPTIMIZER_HIDE_VAR(neq);
     111             :         } else
     112             : #endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
     113             :         {
     114             :                 neq |= *(unsigned char *)(a)    ^ *(unsigned char *)(b);
     115             :                 OPTIMIZER_HIDE_VAR(neq);
     116             :                 neq |= *(unsigned char *)(a+1)  ^ *(unsigned char *)(b+1);
     117             :                 OPTIMIZER_HIDE_VAR(neq);
     118             :                 neq |= *(unsigned char *)(a+2)  ^ *(unsigned char *)(b+2);
     119             :                 OPTIMIZER_HIDE_VAR(neq);
     120             :                 neq |= *(unsigned char *)(a+3)  ^ *(unsigned char *)(b+3);
     121             :                 OPTIMIZER_HIDE_VAR(neq);
     122             :                 neq |= *(unsigned char *)(a+4)  ^ *(unsigned char *)(b+4);
     123             :                 OPTIMIZER_HIDE_VAR(neq);
     124             :                 neq |= *(unsigned char *)(a+5)  ^ *(unsigned char *)(b+5);
     125             :                 OPTIMIZER_HIDE_VAR(neq);
     126             :                 neq |= *(unsigned char *)(a+6)  ^ *(unsigned char *)(b+6);
     127             :                 OPTIMIZER_HIDE_VAR(neq);
     128             :                 neq |= *(unsigned char *)(a+7)  ^ *(unsigned char *)(b+7);
     129             :                 OPTIMIZER_HIDE_VAR(neq);
     130             :                 neq |= *(unsigned char *)(a+8)  ^ *(unsigned char *)(b+8);
     131             :                 OPTIMIZER_HIDE_VAR(neq);
     132             :                 neq |= *(unsigned char *)(a+9)  ^ *(unsigned char *)(b+9);
     133             :                 OPTIMIZER_HIDE_VAR(neq);
     134             :                 neq |= *(unsigned char *)(a+10) ^ *(unsigned char *)(b+10);
     135             :                 OPTIMIZER_HIDE_VAR(neq);
     136             :                 neq |= *(unsigned char *)(a+11) ^ *(unsigned char *)(b+11);
     137             :                 OPTIMIZER_HIDE_VAR(neq);
     138             :                 neq |= *(unsigned char *)(a+12) ^ *(unsigned char *)(b+12);
     139             :                 OPTIMIZER_HIDE_VAR(neq);
     140             :                 neq |= *(unsigned char *)(a+13) ^ *(unsigned char *)(b+13);
     141             :                 OPTIMIZER_HIDE_VAR(neq);
     142             :                 neq |= *(unsigned char *)(a+14) ^ *(unsigned char *)(b+14);
     143             :                 OPTIMIZER_HIDE_VAR(neq);
     144             :                 neq |= *(unsigned char *)(a+15) ^ *(unsigned char *)(b+15);
     145             :                 OPTIMIZER_HIDE_VAR(neq);
     146             :         }
     147             : 
     148           0 :         return neq;
     149             : }
     150             : 
     151             : /* Compare two areas of memory without leaking timing information,
     152             :  * and with special optimizations for common sizes.  Users should
     153             :  * not call this function directly, but should instead use
     154             :  * crypto_memneq defined in crypto/algapi.h.
     155             :  */
     156           0 : noinline unsigned long __crypto_memneq(const void *a, const void *b,
     157             :                                        size_t size)
     158             : {
     159           0 :         switch (size) {
     160             :         case 16:
     161           0 :                 return __crypto_memneq_16(a, b);
     162           0 :         default:
     163           0 :                 return __crypto_memneq_generic(a, b, size);
     164             :         }
     165             : }
     166             : EXPORT_SYMBOL(__crypto_memneq);
     167             : 
     168             : #endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */

Generated by: LCOV version 1.14