diff options
author | Adrian Bunk <bunk@stusta.de> | 2019-06-19 21:04:22 +0300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-06-30 22:34:23 +0100 |
commit | ee0e9eaafed96587b6f1c6b995cd7d5927170c21 (patch) | |
tree | c3e3b3602923c23aa0614a44b3b4049e6f340dea /meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-Add-helper-functions-for-constant-time-operations.patch | |
parent | 76c220e5fe43aef1014e6eec7f0136c2b34be308 (diff) | |
download | poky-ee0e9eaafed96587b6f1c6b995cd7d5927170c21.tar.gz |
wpa-supplicant: Fix CVE-2019-9494 CVE-2019-9495 CVE-2019-9496 CVE-2019-9497 CVE-2019-9498 CVE-2019-9499 CVE-2019-11555
(From OE-Core rev: ae8e0440fc1177bf44e46804e1f5927cb86f8324)
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-Add-helper-functions-for-constant-time-operations.patch')
-rw-r--r-- | meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-Add-helper-functions-for-constant-time-operations.patch | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-Add-helper-functions-for-constant-time-operations.patch b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-Add-helper-functions-for-constant-time-operations.patch new file mode 100644 index 0000000000..fd6f2ce158 --- /dev/null +++ b/meta/recipes-connectivity/wpa-supplicant/wpa-supplicant/0002-Add-helper-functions-for-constant-time-operations.patch | |||
@@ -0,0 +1,222 @@ | |||
1 | From 6e34f618d37ddbb5854c42e2ad4fca83492fa7b7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jouni Malinen <jouni@codeaurora.org> | ||
3 | Date: Wed, 27 Feb 2019 18:38:30 +0200 | ||
4 | Subject: [PATCH 02/14] Add helper functions for constant time operations | ||
5 | |||
6 | These functions can be used to help implement constant time operations | ||
7 | for various cryptographic operations that must minimize externally | ||
8 | observable differences in processing (both in timing and also in | ||
9 | internal cache use, etc.). | ||
10 | |||
11 | This is related to CVE-2019-9494 and CVE-2019-9495. | ||
12 | |||
13 | Signed-off-by: Jouni Malinen <jouni@codeaurora.org> | ||
14 | Signed-off-by: Adrian Bunk <bunk@stusta.de> | ||
15 | Upstream-Status: Backport | ||
16 | CVE: CVE-2019-9494 | ||
17 | CVE: CVE-2019-9495 | ||
18 | --- | ||
19 | src/utils/const_time.h | 191 +++++++++++++++++++++++++++++++++++++++++++++++++ | ||
20 | 1 file changed, 191 insertions(+) | ||
21 | create mode 100644 src/utils/const_time.h | ||
22 | |||
23 | diff --git a/src/utils/const_time.h b/src/utils/const_time.h | ||
24 | new file mode 100644 | ||
25 | index 0000000..ab8f611 | ||
26 | --- /dev/null | ||
27 | +++ b/src/utils/const_time.h | ||
28 | @@ -0,0 +1,191 @@ | ||
29 | +/* | ||
30 | + * Helper functions for constant time operations | ||
31 | + * Copyright (c) 2019, The Linux Foundation | ||
32 | + * | ||
33 | + * This software may be distributed under the terms of the BSD license. | ||
34 | + * See README for more details. | ||
35 | + * | ||
36 | + * These helper functions can be used to implement logic that needs to minimize | ||
37 | + * externally visible differences in execution path by avoiding use of branches, | ||
38 | + * avoiding early termination or other time differences, and forcing same memory | ||
39 | + * access pattern regardless of values. | ||
40 | + */ | ||
41 | + | ||
42 | +#ifndef CONST_TIME_H | ||
43 | +#define CONST_TIME_H | ||
44 | + | ||
45 | + | ||
46 | +#if defined(__clang__) | ||
47 | +#define NO_UBSAN_UINT_OVERFLOW \ | ||
48 | + __attribute__((no_sanitize("unsigned-integer-overflow"))) | ||
49 | +#else | ||
50 | +#define NO_UBSAN_UINT_OVERFLOW | ||
51 | +#endif | ||
52 | + | ||
53 | + | ||
54 | +/** | ||
55 | + * const_time_fill_msb - Fill all bits with MSB value | ||
56 | + * @val: Input value | ||
57 | + * Returns: Value with all the bits set to the MSB of the input val | ||
58 | + */ | ||
59 | +static inline unsigned int const_time_fill_msb(unsigned int val) | ||
60 | +{ | ||
61 | + /* Move the MSB to LSB and multiple by -1 to fill in all bits. */ | ||
62 | + return (val >> (sizeof(val) * 8 - 1)) * ~0U; | ||
63 | +} | ||
64 | + | ||
65 | + | ||
66 | +/* Returns: -1 if val is zero; 0 if val is not zero */ | ||
67 | +static inline unsigned int const_time_is_zero(unsigned int val) | ||
68 | + NO_UBSAN_UINT_OVERFLOW | ||
69 | +{ | ||
70 | + /* Set MSB to 1 for 0 and fill rest of bits with the MSB value */ | ||
71 | + return const_time_fill_msb(~val & (val - 1)); | ||
72 | +} | ||
73 | + | ||
74 | + | ||
75 | +/* Returns: -1 if a == b; 0 if a != b */ | ||
76 | +static inline unsigned int const_time_eq(unsigned int a, unsigned int b) | ||
77 | +{ | ||
78 | + return const_time_is_zero(a ^ b); | ||
79 | +} | ||
80 | + | ||
81 | + | ||
82 | +/* Returns: -1 if a == b; 0 if a != b */ | ||
83 | +static inline u8 const_time_eq_u8(unsigned int a, unsigned int b) | ||
84 | +{ | ||
85 | + return (u8) const_time_eq(a, b); | ||
86 | +} | ||
87 | + | ||
88 | + | ||
89 | +/** | ||
90 | + * const_time_eq_bin - Constant time memory comparison | ||
91 | + * @a: First buffer to compare | ||
92 | + * @b: Second buffer to compare | ||
93 | + * @len: Number of octets to compare | ||
94 | + * Returns: -1 if buffers are equal, 0 if not | ||
95 | + * | ||
96 | + * This function is meant for comparing passwords or hash values where | ||
97 | + * difference in execution time or memory access pattern could provide external | ||
98 | + * observer information about the location of the difference in the memory | ||
99 | + * buffers. The return value does not behave like memcmp(), i.e., | ||
100 | + * const_time_eq_bin() cannot be used to sort items into a defined order. Unlike | ||
101 | + * memcmp(), the execution time of const_time_eq_bin() does not depend on the | ||
102 | + * contents of the compared memory buffers, but only on the total compared | ||
103 | + * length. | ||
104 | + */ | ||
105 | +static inline unsigned int const_time_eq_bin(const void *a, const void *b, | ||
106 | + size_t len) | ||
107 | +{ | ||
108 | + const u8 *aa = a; | ||
109 | + const u8 *bb = b; | ||
110 | + size_t i; | ||
111 | + u8 res = 0; | ||
112 | + | ||
113 | + for (i = 0; i < len; i++) | ||
114 | + res |= aa[i] ^ bb[i]; | ||
115 | + | ||
116 | + return const_time_is_zero(res); | ||
117 | +} | ||
118 | + | ||
119 | + | ||
120 | +/** | ||
121 | + * const_time_select - Constant time unsigned int selection | ||
122 | + * @mask: 0 (false) or -1 (true) to identify which value to select | ||
123 | + * @true_val: Value to select for the true case | ||
124 | + * @false_val: Value to select for the false case | ||
125 | + * Returns: true_val if mask == -1, false_val if mask == 0 | ||
126 | + */ | ||
127 | +static inline unsigned int const_time_select(unsigned int mask, | ||
128 | + unsigned int true_val, | ||
129 | + unsigned int false_val) | ||
130 | +{ | ||
131 | + return (mask & true_val) | (~mask & false_val); | ||
132 | +} | ||
133 | + | ||
134 | + | ||
135 | +/** | ||
136 | + * const_time_select_int - Constant time int selection | ||
137 | + * @mask: 0 (false) or -1 (true) to identify which value to select | ||
138 | + * @true_val: Value to select for the true case | ||
139 | + * @false_val: Value to select for the false case | ||
140 | + * Returns: true_val if mask == -1, false_val if mask == 0 | ||
141 | + */ | ||
142 | +static inline int const_time_select_int(unsigned int mask, int true_val, | ||
143 | + int false_val) | ||
144 | +{ | ||
145 | + return (int) const_time_select(mask, (unsigned int) true_val, | ||
146 | + (unsigned int) false_val); | ||
147 | +} | ||
148 | + | ||
149 | + | ||
150 | +/** | ||
151 | + * const_time_select_u8 - Constant time u8 selection | ||
152 | + * @mask: 0 (false) or -1 (true) to identify which value to select | ||
153 | + * @true_val: Value to select for the true case | ||
154 | + * @false_val: Value to select for the false case | ||
155 | + * Returns: true_val if mask == -1, false_val if mask == 0 | ||
156 | + */ | ||
157 | +static inline u8 const_time_select_u8(u8 mask, u8 true_val, u8 false_val) | ||
158 | +{ | ||
159 | + return (u8) const_time_select(mask, true_val, false_val); | ||
160 | +} | ||
161 | + | ||
162 | + | ||
163 | +/** | ||
164 | + * const_time_select_s8 - Constant time s8 selection | ||
165 | + * @mask: 0 (false) or -1 (true) to identify which value to select | ||
166 | + * @true_val: Value to select for the true case | ||
167 | + * @false_val: Value to select for the false case | ||
168 | + * Returns: true_val if mask == -1, false_val if mask == 0 | ||
169 | + */ | ||
170 | +static inline s8 const_time_select_s8(u8 mask, s8 true_val, s8 false_val) | ||
171 | +{ | ||
172 | + return (s8) const_time_select(mask, (unsigned int) true_val, | ||
173 | + (unsigned int) false_val); | ||
174 | +} | ||
175 | + | ||
176 | + | ||
177 | +/** | ||
178 | + * const_time_select_bin - Constant time binary buffer selection copy | ||
179 | + * @mask: 0 (false) or -1 (true) to identify which value to copy | ||
180 | + * @true_val: Buffer to copy for the true case | ||
181 | + * @false_val: Buffer to copy for the false case | ||
182 | + * @len: Number of octets to copy | ||
183 | + * @dst: Destination buffer for the copy | ||
184 | + * | ||
185 | + * This function copies the specified buffer into the destination buffer using | ||
186 | + * operations with identical memory access pattern regardless of which buffer | ||
187 | + * is being copied. | ||
188 | + */ | ||
189 | +static inline void const_time_select_bin(u8 mask, const u8 *true_val, | ||
190 | + const u8 *false_val, size_t len, | ||
191 | + u8 *dst) | ||
192 | +{ | ||
193 | + size_t i; | ||
194 | + | ||
195 | + for (i = 0; i < len; i++) | ||
196 | + dst[i] = const_time_select_u8(mask, true_val[i], false_val[i]); | ||
197 | +} | ||
198 | + | ||
199 | + | ||
200 | +static inline int const_time_memcmp(const void *a, const void *b, size_t len) | ||
201 | +{ | ||
202 | + const u8 *aa = a; | ||
203 | + const u8 *bb = b; | ||
204 | + int diff, res = 0; | ||
205 | + unsigned int mask; | ||
206 | + | ||
207 | + if (len == 0) | ||
208 | + return 0; | ||
209 | + do { | ||
210 | + len--; | ||
211 | + diff = (int) aa[len] - (int) bb[len]; | ||
212 | + mask = const_time_is_zero((unsigned int) diff); | ||
213 | + res = const_time_select_int(mask, res, diff); | ||
214 | + } while (len); | ||
215 | + | ||
216 | + return res; | ||
217 | +} | ||
218 | + | ||
219 | +#endif /* CONST_TIME_H */ | ||
220 | -- | ||
221 | 2.7.4 | ||
222 | |||