Root/
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 | __crypto_memneq_generic(const void *a, const void *b, size_t size) |
69 | { |
70 | unsigned long neq = 0; |
71 | |
72 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) |
73 | while (size >= sizeof(unsigned long)) { |
74 | neq |= *(unsigned long *)a ^ *(unsigned long *)b; |
75 | OPTIMIZER_HIDE_VAR(neq); |
76 | a += sizeof(unsigned long); |
77 | b += sizeof(unsigned long); |
78 | size -= sizeof(unsigned long); |
79 | } |
80 | #endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */ |
81 | while (size > 0) { |
82 | neq |= *(unsigned char *)a ^ *(unsigned char *)b; |
83 | OPTIMIZER_HIDE_VAR(neq); |
84 | a += 1; |
85 | b += 1; |
86 | size -= 1; |
87 | } |
88 | return neq; |
89 | } |
90 | |
91 | /* Loop-free fast-path for frequently used 16-byte size */ |
92 | static inline unsigned long __crypto_memneq_16(const void *a, const void *b) |
93 | { |
94 | unsigned long neq = 0; |
95 | |
96 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS |
97 | if (sizeof(unsigned long) == 8) { |
98 | neq |= *(unsigned long *)(a) ^ *(unsigned long *)(b); |
99 | OPTIMIZER_HIDE_VAR(neq); |
100 | neq |= *(unsigned long *)(a+8) ^ *(unsigned long *)(b+8); |
101 | 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 | 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 | noinline unsigned long __crypto_memneq(const void *a, const void *b, |
157 | size_t size) |
158 | { |
159 | switch (size) { |
160 | case 16: |
161 | return __crypto_memneq_16(a, b); |
162 | default: |
163 | return __crypto_memneq_generic(a, b, size); |
164 | } |
165 | } |
166 | EXPORT_SYMBOL(__crypto_memneq); |
167 | |
168 | #endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */ |
169 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9