Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/ring-0.17.8/crypto/internal.h
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@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@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@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@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
/* ====================================================================
58
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
59
 *
60
 * Redistribution and use in source and binary forms, with or without
61
 * modification, are permitted provided that the following conditions
62
 * are met:
63
 *
64
 * 1. Redistributions of source code must retain the above copyright
65
 *    notice, this list of conditions and the following disclaimer.
66
 *
67
 * 2. Redistributions in binary form must reproduce the above copyright
68
 *    notice, this list of conditions and the following disclaimer in
69
 *    the documentation and/or other materials provided with the
70
 *    distribution.
71
 *
72
 * 3. All advertising materials mentioning features or use of this
73
 *    software must display the following acknowledgment:
74
 *    "This product includes software developed by the OpenSSL Project
75
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76
 *
77
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78
 *    endorse or promote products derived from this software without
79
 *    prior written permission. For written permission, please contact
80
 *    openssl-core@openssl.org.
81
 *
82
 * 5. Products derived from this software may not be called "OpenSSL"
83
 *    nor may "OpenSSL" appear in their names without prior written
84
 *    permission of the OpenSSL Project.
85
 *
86
 * 6. Redistributions of any form whatsoever must retain the following
87
 *    acknowledgment:
88
 *    "This product includes software developed by the OpenSSL Project
89
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90
 *
91
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102
 * OF THE POSSIBILITY OF SUCH DAMAGE.
103
 * ====================================================================
104
 *
105
 * This product includes cryptographic software written by Eric Young
106
 * (eay@cryptsoft.com).  This product includes software written by Tim
107
 * Hudson (tjh@cryptsoft.com). */
108
109
#ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H
110
#define OPENSSL_HEADER_CRYPTO_INTERNAL_H
111
112
#include <ring-core/base.h> // Must be first.
113
114
#include "ring-core/arm_arch.h"
115
#include "ring-core/check.h"
116
117
#if defined(__clang__)
118
// Don't require prototypes for functions defined in C that are only
119
// used from Rust.
120
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
121
#endif
122
123
#if defined(__GNUC__) && \
124
    (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
125
// |alignas| and |alignof| were added in C11. GCC added support in version 4.8.
126
// Testing for __STDC_VERSION__/__cplusplus doesn't work because 4.7 already
127
// reports support for C11.
128
0
#define alignas(x) __attribute__ ((aligned (x)))
129
#elif defined(_MSC_VER) && !defined(__clang__)
130
#define alignas(x) __declspec(align(x))
131
#else
132
#include <stdalign.h>
133
#endif
134
135
#if defined(__clang__) || defined(__GNUC__)
136
#define RING_NOINLINE __attribute__((noinline))
137
#elif defined(_MSC_VER)
138
#define RING_NOINLINE __declspec(noinline)
139
#else
140
#define RING_NOINLINE
141
#endif
142
143
// Some C compilers require a useless cast when dealing with arrays for the
144
// reason explained in
145
// https://gustedt.wordpress.com/2011/02/12/const-and-arrays/
146
#if defined(__clang__) || defined(_MSC_VER)
147
#define RING_CORE_POINTLESS_ARRAY_CONST_CAST(cast)
148
#else
149
#define RING_CORE_POINTLESS_ARRAY_CONST_CAST(cast) cast
150
#endif
151
152
// `uint8_t` isn't guaranteed to be 'unsigned char' and only 'char' and
153
// 'unsigned char' are allowed to alias according to ISO C.
154
typedef unsigned char aliasing_uint8_t;
155
156
#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
157
#define BORINGSSL_HAS_UINT128
158
typedef __int128_t int128_t;
159
typedef __uint128_t uint128_t;
160
#endif
161
162
// Pointer utility functions.
163
164
// buffers_alias returns one if |a| and |b| alias and zero otherwise.
165
static inline int buffers_alias(const void *a, size_t a_bytes,
166
0
                                const void *b, size_t b_bytes) {
167
0
  // Cast |a| and |b| to integers. In C, pointer comparisons between unrelated
168
0
  // objects are undefined whereas pointer to integer conversions are merely
169
0
  // implementation-defined. We assume the implementation defined it in a sane
170
0
  // way.
171
0
  uintptr_t a_u = (uintptr_t)a;
172
0
  uintptr_t b_u = (uintptr_t)b;
173
0
  return a_u + a_bytes > b_u && b_u + b_bytes > a_u;
174
0
}
Unexecuted instantiation: curve25519.c:buffers_alias
Unexecuted instantiation: aes_nohw.c:buffers_alias
Unexecuted instantiation: montgomery.c:buffers_alias
Unexecuted instantiation: montgomery_inv.c:buffers_alias
Unexecuted instantiation: gfp_p384.c:buffers_alias
Unexecuted instantiation: limbs.c:buffers_alias
Unexecuted instantiation: mem.c:buffers_alias
Unexecuted instantiation: cpu_intel.c:buffers_alias
Unexecuted instantiation: curve25519_64_adx.c:buffers_alias
Unexecuted instantiation: poly1305_vec.c:buffers_alias
Unexecuted instantiation: p256-nistz.c:buffers_alias
Unexecuted instantiation: ecp_nistz.c:buffers_alias
175
176
177
// Constant-time utility functions.
178
//
179
// The following methods return a bitmask of all ones (0xff...f) for true and 0
180
// for false. This is useful for choosing a value based on the result of a
181
// conditional in constant time. For example,
182
//
183
// if (a < b) {
184
//   c = a;
185
// } else {
186
//   c = b;
187
// }
188
//
189
// can be written as
190
//
191
// crypto_word_t lt = constant_time_lt_w(a, b);
192
// c = constant_time_select_w(lt, a, b);
193
194
#if defined(__GNUC__) || defined(__clang__)
195
#pragma GCC diagnostic push
196
#pragma GCC diagnostic ignored "-Wconversion"
197
#endif
198
#if defined(_MSC_VER) && !defined(__clang__)
199
#pragma warning(push)
200
// '=': conversion from 'crypto_word_t' to 'uint8_t', possible loss of data
201
#pragma warning(disable: 4242)
202
//  'initializing': conversion from 'crypto_word_t' to 'uint8_t', ...
203
#pragma warning(disable: 4244)
204
#endif
205
206
// crypto_word_t is the type that most constant-time functions use. Ideally we
207
// would like it to be |size_t|, but NaCl builds in 64-bit mode with 32-bit
208
// pointers, which means that |size_t| can be 32 bits when |BN_ULONG| is 64
209
// bits. Since we want to be able to do constant-time operations on a
210
// |BN_ULONG|, |crypto_word_t| is defined as an unsigned value with the native
211
// word length.
212
#if defined(OPENSSL_64_BIT)
213
typedef uint64_t crypto_word_t;
214
0
#define CRYPTO_WORD_BITS (64u)
215
#elif defined(OPENSSL_32_BIT)
216
typedef uint32_t crypto_word_t;
217
#define CRYPTO_WORD_BITS (32u)
218
#else
219
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
220
#endif
221
222
0
#define CONSTTIME_TRUE_W ~((crypto_word_t)0)
223
#define CONSTTIME_FALSE_W ((crypto_word_t)0)
224
225
// value_barrier_w returns |a|, but prevents GCC and Clang from reasoning about
226
// the returned value. This is used to mitigate compilers undoing constant-time
227
// code, until we can express our requirements directly in the language.
228
//
229
// Note the compiler is aware that |value_barrier_w| has no side effects and
230
// always has the same output for a given input. This allows it to eliminate
231
// dead code, move computations across loops, and vectorize.
232
0
static inline crypto_word_t value_barrier_w(crypto_word_t a) {
233
0
#if defined(__GNUC__) || defined(__clang__)
234
0
  __asm__("" : "+r"(a) : /* no inputs */);
235
0
#endif
236
0
  return a;
237
0
}
Unexecuted instantiation: curve25519.c:value_barrier_w
Unexecuted instantiation: aes_nohw.c:value_barrier_w
Unexecuted instantiation: montgomery.c:value_barrier_w
Unexecuted instantiation: montgomery_inv.c:value_barrier_w
Unexecuted instantiation: gfp_p384.c:value_barrier_w
Unexecuted instantiation: limbs.c:value_barrier_w
Unexecuted instantiation: mem.c:value_barrier_w
Unexecuted instantiation: cpu_intel.c:value_barrier_w
Unexecuted instantiation: curve25519_64_adx.c:value_barrier_w
Unexecuted instantiation: poly1305_vec.c:value_barrier_w
Unexecuted instantiation: p256-nistz.c:value_barrier_w
Unexecuted instantiation: ecp_nistz.c:value_barrier_w
238
239
// |value_barrier_u8| could be defined as above, but compilers other than
240
// clang seem to still materialize 0x00..00MM instead of reusing 0x??..??MM.
241
242
// constant_time_msb_w returns the given value with the MSB copied to all the
243
// other bits.
244
0
static inline crypto_word_t constant_time_msb_w(crypto_word_t a) {
245
0
  return 0u - (a >> (sizeof(a) * 8 - 1));
246
0
}
Unexecuted instantiation: curve25519.c:constant_time_msb_w
Unexecuted instantiation: aes_nohw.c:constant_time_msb_w
Unexecuted instantiation: montgomery.c:constant_time_msb_w
Unexecuted instantiation: montgomery_inv.c:constant_time_msb_w
Unexecuted instantiation: gfp_p384.c:constant_time_msb_w
Unexecuted instantiation: limbs.c:constant_time_msb_w
Unexecuted instantiation: mem.c:constant_time_msb_w
Unexecuted instantiation: cpu_intel.c:constant_time_msb_w
Unexecuted instantiation: curve25519_64_adx.c:constant_time_msb_w
Unexecuted instantiation: poly1305_vec.c:constant_time_msb_w
Unexecuted instantiation: p256-nistz.c:constant_time_msb_w
Unexecuted instantiation: ecp_nistz.c:constant_time_msb_w
247
248
// constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise.
249
0
static inline crypto_word_t constant_time_is_zero_w(crypto_word_t a) {
250
  // Here is an SMT-LIB verification of this formula:
251
  //
252
  // (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32)
253
  //   (bvand (bvnot a) (bvsub a #x00000001))
254
  // )
255
  //
256
  // (declare-fun a () (_ BitVec 32))
257
  //
258
  // (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000))))
259
  // (check-sat)
260
  // (get-model)
261
0
  return constant_time_msb_w(~a & (a - 1));
262
0
}
Unexecuted instantiation: curve25519.c:constant_time_is_zero_w
Unexecuted instantiation: aes_nohw.c:constant_time_is_zero_w
Unexecuted instantiation: montgomery.c:constant_time_is_zero_w
Unexecuted instantiation: montgomery_inv.c:constant_time_is_zero_w
Unexecuted instantiation: gfp_p384.c:constant_time_is_zero_w
Unexecuted instantiation: limbs.c:constant_time_is_zero_w
Unexecuted instantiation: mem.c:constant_time_is_zero_w
Unexecuted instantiation: cpu_intel.c:constant_time_is_zero_w
Unexecuted instantiation: curve25519_64_adx.c:constant_time_is_zero_w
Unexecuted instantiation: poly1305_vec.c:constant_time_is_zero_w
Unexecuted instantiation: p256-nistz.c:constant_time_is_zero_w
Unexecuted instantiation: ecp_nistz.c:constant_time_is_zero_w
263
264
0
static inline crypto_word_t constant_time_is_nonzero_w(crypto_word_t a) {
265
0
  return ~constant_time_is_zero_w(a);
266
0
}
Unexecuted instantiation: curve25519.c:constant_time_is_nonzero_w
Unexecuted instantiation: aes_nohw.c:constant_time_is_nonzero_w
Unexecuted instantiation: montgomery.c:constant_time_is_nonzero_w
Unexecuted instantiation: montgomery_inv.c:constant_time_is_nonzero_w
Unexecuted instantiation: gfp_p384.c:constant_time_is_nonzero_w
Unexecuted instantiation: limbs.c:constant_time_is_nonzero_w
Unexecuted instantiation: mem.c:constant_time_is_nonzero_w
Unexecuted instantiation: cpu_intel.c:constant_time_is_nonzero_w
Unexecuted instantiation: curve25519_64_adx.c:constant_time_is_nonzero_w
Unexecuted instantiation: poly1305_vec.c:constant_time_is_nonzero_w
Unexecuted instantiation: p256-nistz.c:constant_time_is_nonzero_w
Unexecuted instantiation: ecp_nistz.c:constant_time_is_nonzero_w
267
268
// constant_time_eq_w returns 0xff..f if a == b and 0 otherwise.
269
static inline crypto_word_t constant_time_eq_w(crypto_word_t a,
270
0
                                               crypto_word_t b) {
271
0
  return constant_time_is_zero_w(a ^ b);
272
0
}
Unexecuted instantiation: curve25519.c:constant_time_eq_w
Unexecuted instantiation: aes_nohw.c:constant_time_eq_w
Unexecuted instantiation: montgomery.c:constant_time_eq_w
Unexecuted instantiation: montgomery_inv.c:constant_time_eq_w
Unexecuted instantiation: gfp_p384.c:constant_time_eq_w
Unexecuted instantiation: limbs.c:constant_time_eq_w
Unexecuted instantiation: mem.c:constant_time_eq_w
Unexecuted instantiation: cpu_intel.c:constant_time_eq_w
Unexecuted instantiation: curve25519_64_adx.c:constant_time_eq_w
Unexecuted instantiation: poly1305_vec.c:constant_time_eq_w
Unexecuted instantiation: p256-nistz.c:constant_time_eq_w
Unexecuted instantiation: ecp_nistz.c:constant_time_eq_w
273
274
// constant_time_select_w returns (mask & a) | (~mask & b). When |mask| is all
275
// 1s or all 0s (as returned by the methods above), the select methods return
276
// either |a| (if |mask| is nonzero) or |b| (if |mask| is zero).
277
static inline crypto_word_t constant_time_select_w(crypto_word_t mask,
278
                                                   crypto_word_t a,
279
0
                                                   crypto_word_t b) {
280
  // Clang recognizes this pattern as a select. While it usually transforms it
281
  // to a cmov, it sometimes further transforms it into a branch, which we do
282
  // not want.
283
  //
284
  // Hiding the value of the mask from the compiler evades this transformation.
285
0
  mask = value_barrier_w(mask);
286
0
  return (mask & a) | (~mask & b);
287
0
}
Unexecuted instantiation: curve25519.c:constant_time_select_w
Unexecuted instantiation: aes_nohw.c:constant_time_select_w
Unexecuted instantiation: montgomery.c:constant_time_select_w
Unexecuted instantiation: montgomery_inv.c:constant_time_select_w
Unexecuted instantiation: gfp_p384.c:constant_time_select_w
Unexecuted instantiation: limbs.c:constant_time_select_w
Unexecuted instantiation: mem.c:constant_time_select_w
Unexecuted instantiation: cpu_intel.c:constant_time_select_w
Unexecuted instantiation: curve25519_64_adx.c:constant_time_select_w
Unexecuted instantiation: poly1305_vec.c:constant_time_select_w
Unexecuted instantiation: p256-nistz.c:constant_time_select_w
Unexecuted instantiation: ecp_nistz.c:constant_time_select_w
288
289
// constant_time_select_8 acts like |constant_time_select| but operates on
290
// 8-bit values.
291
static inline uint8_t constant_time_select_8(crypto_word_t mask, uint8_t a,
292
0
                                             uint8_t b) {
293
  // |mask| is a word instead of |uint8_t| to avoid materializing 0x000..0MM
294
  // Making both |mask| and its value barrier |uint8_t| would allow the compiler
295
  // to materialize 0x????..?MM instead, but only clang is that clever.
296
  // However, vectorization of bitwise operations seems to work better on
297
  // |uint8_t| than a mix of |uint64_t| and |uint8_t|, so |m| is cast to
298
  // |uint8_t| after the value barrier but before the bitwise operations.
299
0
  uint8_t m = value_barrier_w(mask);
300
0
  return (m & a) | (~m & b);
301
0
}
Unexecuted instantiation: curve25519.c:constant_time_select_8
Unexecuted instantiation: aes_nohw.c:constant_time_select_8
Unexecuted instantiation: montgomery.c:constant_time_select_8
Unexecuted instantiation: montgomery_inv.c:constant_time_select_8
Unexecuted instantiation: gfp_p384.c:constant_time_select_8
Unexecuted instantiation: limbs.c:constant_time_select_8
Unexecuted instantiation: mem.c:constant_time_select_8
Unexecuted instantiation: cpu_intel.c:constant_time_select_8
Unexecuted instantiation: curve25519_64_adx.c:constant_time_select_8
Unexecuted instantiation: poly1305_vec.c:constant_time_select_8
Unexecuted instantiation: p256-nistz.c:constant_time_select_8
Unexecuted instantiation: ecp_nistz.c:constant_time_select_8
302
303
// constant_time_conditional_memcpy copies |n| bytes from |src| to |dst| if
304
// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory
305
// ranges at |dst| and |src| must not overlap, as when calling |memcpy|.
306
static inline void constant_time_conditional_memcpy(void *dst, const void *src,
307
                                                    const size_t n,
308
0
                                                    const crypto_word_t mask) {
309
0
  debug_assert_nonsecret(!buffers_alias(dst, n, src, n));
310
0
  uint8_t *out = (uint8_t *)dst;
311
0
  const uint8_t *in = (const uint8_t *)src;
312
0
  for (size_t i = 0; i < n; i++) {
313
0
    out[i] = constant_time_select_8(mask, in[i], out[i]);
314
0
  }
315
0
}
Unexecuted instantiation: curve25519.c:constant_time_conditional_memcpy
Unexecuted instantiation: aes_nohw.c:constant_time_conditional_memcpy
Unexecuted instantiation: montgomery.c:constant_time_conditional_memcpy
Unexecuted instantiation: montgomery_inv.c:constant_time_conditional_memcpy
Unexecuted instantiation: gfp_p384.c:constant_time_conditional_memcpy
Unexecuted instantiation: limbs.c:constant_time_conditional_memcpy
Unexecuted instantiation: mem.c:constant_time_conditional_memcpy
Unexecuted instantiation: cpu_intel.c:constant_time_conditional_memcpy
Unexecuted instantiation: curve25519_64_adx.c:constant_time_conditional_memcpy
Unexecuted instantiation: poly1305_vec.c:constant_time_conditional_memcpy
Unexecuted instantiation: p256-nistz.c:constant_time_conditional_memcpy
Unexecuted instantiation: ecp_nistz.c:constant_time_conditional_memcpy
316
317
// constant_time_conditional_memxor xors |n| bytes from |src| to |dst| if
318
// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory
319
// ranges at |dst| and |src| must not overlap, as when calling |memcpy|.
320
static inline void constant_time_conditional_memxor(void *dst, const void *src,
321
                                                    const size_t n,
322
0
                                                    const crypto_word_t mask) {
323
0
  debug_assert_nonsecret(!buffers_alias(dst, n, src, n));
324
0
  aliasing_uint8_t *out = dst;
325
0
  const aliasing_uint8_t *in = src;
326
0
  for (size_t i = 0; i < n; i++) {
327
0
    out[i] ^= value_barrier_w(mask) & in[i];
328
0
  }
329
0
}
Unexecuted instantiation: curve25519.c:constant_time_conditional_memxor
Unexecuted instantiation: aes_nohw.c:constant_time_conditional_memxor
Unexecuted instantiation: montgomery.c:constant_time_conditional_memxor
Unexecuted instantiation: montgomery_inv.c:constant_time_conditional_memxor
Unexecuted instantiation: gfp_p384.c:constant_time_conditional_memxor
Unexecuted instantiation: limbs.c:constant_time_conditional_memxor
Unexecuted instantiation: mem.c:constant_time_conditional_memxor
Unexecuted instantiation: cpu_intel.c:constant_time_conditional_memxor
Unexecuted instantiation: curve25519_64_adx.c:constant_time_conditional_memxor
Unexecuted instantiation: poly1305_vec.c:constant_time_conditional_memxor
Unexecuted instantiation: p256-nistz.c:constant_time_conditional_memxor
Unexecuted instantiation: ecp_nistz.c:constant_time_conditional_memxor
330
331
#if defined(_MSC_VER) && !defined(__clang__)
332
// '=': conversion from 'int64_t' to 'int32_t', possible loss of data
333
#pragma warning(pop)
334
#endif
335
#if defined(__GNUC__) || defined(__clang__)
336
#pragma GCC diagnostic pop
337
#endif
338
339
#if defined(BORINGSSL_CONSTANT_TIME_VALIDATION)
340
341
// CONSTTIME_SECRET takes a pointer and a number of bytes and marks that region
342
// of memory as secret. Secret data is tracked as it flows to registers and
343
// other parts of a memory. If secret data is used as a condition for a branch,
344
// or as a memory index, it will trigger warnings in valgrind.
345
#define CONSTTIME_SECRET(ptr, len) VALGRIND_MAKE_MEM_UNDEFINED(ptr, len)
346
347
// CONSTTIME_DECLASSIFY takes a pointer and a number of bytes and marks that
348
// region of memory as public. Public data is not subject to constant-time
349
// rules.
350
#define CONSTTIME_DECLASSIFY(ptr, len) VALGRIND_MAKE_MEM_DEFINED(ptr, len)
351
352
#else
353
354
#define CONSTTIME_SECRET(ptr, len)
355
#define CONSTTIME_DECLASSIFY(ptr, len)
356
357
#endif  // BORINGSSL_CONSTANT_TIME_VALIDATION
358
359
0
static inline crypto_word_t constant_time_declassify_w(crypto_word_t v) {
360
0
  // Return |v| through a value barrier to be safe. Valgrind-based constant-time
361
0
  // validation is partly to check the compiler has not undone any constant-time
362
0
  // work. Any place |BORINGSSL_CONSTANT_TIME_VALIDATION| influences
363
0
  // optimizations, this validation is inaccurate.
364
0
  //
365
0
  // However, by sending pointers through valgrind, we likely inhibit escape
366
0
  // analysis. On local variables, particularly booleans, we likely
367
0
  // significantly impact optimizations.
368
0
  //
369
0
  // Thus, to be safe, stick a value barrier, in hopes of comparably inhibiting
370
0
  // compiler analysis.
371
0
  CONSTTIME_DECLASSIFY(&v, sizeof(v));
372
0
  return value_barrier_w(v);
373
0
}
Unexecuted instantiation: curve25519.c:constant_time_declassify_w
Unexecuted instantiation: aes_nohw.c:constant_time_declassify_w
Unexecuted instantiation: montgomery.c:constant_time_declassify_w
Unexecuted instantiation: montgomery_inv.c:constant_time_declassify_w
Unexecuted instantiation: gfp_p384.c:constant_time_declassify_w
Unexecuted instantiation: limbs.c:constant_time_declassify_w
Unexecuted instantiation: mem.c:constant_time_declassify_w
Unexecuted instantiation: cpu_intel.c:constant_time_declassify_w
Unexecuted instantiation: curve25519_64_adx.c:constant_time_declassify_w
Unexecuted instantiation: poly1305_vec.c:constant_time_declassify_w
Unexecuted instantiation: p256-nistz.c:constant_time_declassify_w
Unexecuted instantiation: ecp_nistz.c:constant_time_declassify_w
374
375
// Endianness conversions.
376
377
#if defined(__GNUC__) && __GNUC__ >= 2
378
0
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
379
0
  return __builtin_bswap32(x);
380
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_bswap4
Unexecuted instantiation: aes_nohw.c:CRYPTO_bswap4
Unexecuted instantiation: montgomery.c:CRYPTO_bswap4
Unexecuted instantiation: montgomery_inv.c:CRYPTO_bswap4
Unexecuted instantiation: gfp_p384.c:CRYPTO_bswap4
Unexecuted instantiation: limbs.c:CRYPTO_bswap4
Unexecuted instantiation: mem.c:CRYPTO_bswap4
Unexecuted instantiation: cpu_intel.c:CRYPTO_bswap4
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_bswap4
Unexecuted instantiation: poly1305_vec.c:CRYPTO_bswap4
Unexecuted instantiation: p256-nistz.c:CRYPTO_bswap4
Unexecuted instantiation: ecp_nistz.c:CRYPTO_bswap4
381
382
0
static inline uint64_t CRYPTO_bswap8(uint64_t x) {
383
0
  return __builtin_bswap64(x);
384
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_bswap8
Unexecuted instantiation: aes_nohw.c:CRYPTO_bswap8
Unexecuted instantiation: montgomery.c:CRYPTO_bswap8
Unexecuted instantiation: montgomery_inv.c:CRYPTO_bswap8
Unexecuted instantiation: gfp_p384.c:CRYPTO_bswap8
Unexecuted instantiation: limbs.c:CRYPTO_bswap8
Unexecuted instantiation: mem.c:CRYPTO_bswap8
Unexecuted instantiation: cpu_intel.c:CRYPTO_bswap8
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_bswap8
Unexecuted instantiation: poly1305_vec.c:CRYPTO_bswap8
Unexecuted instantiation: p256-nistz.c:CRYPTO_bswap8
Unexecuted instantiation: ecp_nistz.c:CRYPTO_bswap8
385
#elif defined(_MSC_VER)
386
#pragma warning(push, 3)
387
#include <stdlib.h>
388
#pragma warning(pop)
389
#pragma intrinsic(_byteswap_uint64, _byteswap_ulong)
390
static inline uint32_t CRYPTO_bswap4(uint32_t x) {
391
  return _byteswap_ulong(x);
392
}
393
394
static inline uint64_t CRYPTO_bswap8(uint64_t x) {
395
  return _byteswap_uint64(x);
396
}
397
#endif
398
399
#if !defined(RING_CORE_NOSTDLIBINC)
400
#include <string.h>
401
#endif
402
403
0
static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) {
404
0
#if !defined(RING_CORE_NOSTDLIBINC)
405
0
  if (n == 0) {
406
0
    return dst;
407
0
  }
408
0
  return memcpy(dst, src, n);
409
#else
410
  aliasing_uint8_t *d = dst;
411
  const aliasing_uint8_t *s = src;
412
  for (size_t i = 0; i < n; ++i) {
413
    d[i] = s[i];
414
  }
415
  return dst;
416
#endif
417
0
}
Unexecuted instantiation: curve25519.c:OPENSSL_memcpy
Unexecuted instantiation: aes_nohw.c:OPENSSL_memcpy
Unexecuted instantiation: montgomery.c:OPENSSL_memcpy
Unexecuted instantiation: montgomery_inv.c:OPENSSL_memcpy
Unexecuted instantiation: gfp_p384.c:OPENSSL_memcpy
Unexecuted instantiation: limbs.c:OPENSSL_memcpy
Unexecuted instantiation: mem.c:OPENSSL_memcpy
Unexecuted instantiation: cpu_intel.c:OPENSSL_memcpy
Unexecuted instantiation: curve25519_64_adx.c:OPENSSL_memcpy
Unexecuted instantiation: poly1305_vec.c:OPENSSL_memcpy
Unexecuted instantiation: p256-nistz.c:OPENSSL_memcpy
Unexecuted instantiation: ecp_nistz.c:OPENSSL_memcpy
418
419
0
static inline void *OPENSSL_memset(void *dst, int c, size_t n) {
420
0
#if !defined(RING_CORE_NOSTDLIBINC)
421
0
  if (n == 0) {
422
0
    return dst;
423
0
  }
424
0
  return memset(dst, c, n);
425
#else
426
  aliasing_uint8_t *d = dst;
427
  for (size_t i = 0; i < n; ++i) {
428
    d[i] = (aliasing_uint8_t)c;
429
  }
430
  return dst;
431
#endif
432
0
}
Unexecuted instantiation: curve25519.c:OPENSSL_memset
Unexecuted instantiation: aes_nohw.c:OPENSSL_memset
Unexecuted instantiation: montgomery.c:OPENSSL_memset
Unexecuted instantiation: montgomery_inv.c:OPENSSL_memset
Unexecuted instantiation: gfp_p384.c:OPENSSL_memset
Unexecuted instantiation: limbs.c:OPENSSL_memset
Unexecuted instantiation: mem.c:OPENSSL_memset
Unexecuted instantiation: cpu_intel.c:OPENSSL_memset
Unexecuted instantiation: curve25519_64_adx.c:OPENSSL_memset
Unexecuted instantiation: poly1305_vec.c:OPENSSL_memset
Unexecuted instantiation: p256-nistz.c:OPENSSL_memset
Unexecuted instantiation: ecp_nistz.c:OPENSSL_memset
433
434
435
// Loads and stores.
436
//
437
// The following functions load and store sized integers with the specified
438
// endianness. They use |memcpy|, and so avoid alignment or strict aliasing
439
// requirements on the input and output pointers.
440
441
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
442
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
443
#define RING_BIG_ENDIAN
444
#endif
445
#endif
446
447
0
static inline uint32_t CRYPTO_load_u32_le(const void *in) {
448
0
  uint32_t v;
449
0
  OPENSSL_memcpy(&v, in, sizeof(v));
450
#if defined(RING_BIG_ENDIAN)
451
  return CRYPTO_bswap4(v);
452
#else
453
0
  return v;
454
0
#endif
455
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_load_u32_le
Unexecuted instantiation: aes_nohw.c:CRYPTO_load_u32_le
Unexecuted instantiation: montgomery.c:CRYPTO_load_u32_le
Unexecuted instantiation: montgomery_inv.c:CRYPTO_load_u32_le
Unexecuted instantiation: gfp_p384.c:CRYPTO_load_u32_le
Unexecuted instantiation: limbs.c:CRYPTO_load_u32_le
Unexecuted instantiation: mem.c:CRYPTO_load_u32_le
Unexecuted instantiation: cpu_intel.c:CRYPTO_load_u32_le
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_load_u32_le
Unexecuted instantiation: poly1305_vec.c:CRYPTO_load_u32_le
Unexecuted instantiation: p256-nistz.c:CRYPTO_load_u32_le
Unexecuted instantiation: ecp_nistz.c:CRYPTO_load_u32_le
456
457
0
static inline void CRYPTO_store_u32_le(void *out, uint32_t v) {
458
0
#if defined(RING_BIG_ENDIAN)
459
0
  v = CRYPTO_bswap4(v);
460
0
#endif
461
0
  OPENSSL_memcpy(out, &v, sizeof(v));
462
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_store_u32_le
Unexecuted instantiation: aes_nohw.c:CRYPTO_store_u32_le
Unexecuted instantiation: montgomery.c:CRYPTO_store_u32_le
Unexecuted instantiation: montgomery_inv.c:CRYPTO_store_u32_le
Unexecuted instantiation: gfp_p384.c:CRYPTO_store_u32_le
Unexecuted instantiation: limbs.c:CRYPTO_store_u32_le
Unexecuted instantiation: mem.c:CRYPTO_store_u32_le
Unexecuted instantiation: cpu_intel.c:CRYPTO_store_u32_le
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_store_u32_le
Unexecuted instantiation: poly1305_vec.c:CRYPTO_store_u32_le
Unexecuted instantiation: p256-nistz.c:CRYPTO_store_u32_le
Unexecuted instantiation: ecp_nistz.c:CRYPTO_store_u32_le
463
464
0
static inline uint32_t CRYPTO_load_u32_be(const void *in) {
465
0
  uint32_t v;
466
0
  OPENSSL_memcpy(&v, in, sizeof(v));
467
0
#if !defined(RING_BIG_ENDIAN)
468
0
  return CRYPTO_bswap4(v);
469
#else
470
  return v;
471
#endif
472
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_load_u32_be
Unexecuted instantiation: aes_nohw.c:CRYPTO_load_u32_be
Unexecuted instantiation: montgomery.c:CRYPTO_load_u32_be
Unexecuted instantiation: montgomery_inv.c:CRYPTO_load_u32_be
Unexecuted instantiation: gfp_p384.c:CRYPTO_load_u32_be
Unexecuted instantiation: limbs.c:CRYPTO_load_u32_be
Unexecuted instantiation: mem.c:CRYPTO_load_u32_be
Unexecuted instantiation: cpu_intel.c:CRYPTO_load_u32_be
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_load_u32_be
Unexecuted instantiation: poly1305_vec.c:CRYPTO_load_u32_be
Unexecuted instantiation: p256-nistz.c:CRYPTO_load_u32_be
Unexecuted instantiation: ecp_nistz.c:CRYPTO_load_u32_be
473
474
0
static inline void CRYPTO_store_u32_be(void *out, uint32_t v) {
475
0
#if !defined(RING_BIG_ENDIAN)
476
0
  v = CRYPTO_bswap4(v);
477
0
#endif
478
0
  OPENSSL_memcpy(out, &v, sizeof(v));
479
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_store_u32_be
Unexecuted instantiation: aes_nohw.c:CRYPTO_store_u32_be
Unexecuted instantiation: montgomery.c:CRYPTO_store_u32_be
Unexecuted instantiation: montgomery_inv.c:CRYPTO_store_u32_be
Unexecuted instantiation: gfp_p384.c:CRYPTO_store_u32_be
Unexecuted instantiation: limbs.c:CRYPTO_store_u32_be
Unexecuted instantiation: mem.c:CRYPTO_store_u32_be
Unexecuted instantiation: cpu_intel.c:CRYPTO_store_u32_be
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_store_u32_be
Unexecuted instantiation: poly1305_vec.c:CRYPTO_store_u32_be
Unexecuted instantiation: p256-nistz.c:CRYPTO_store_u32_be
Unexecuted instantiation: ecp_nistz.c:CRYPTO_store_u32_be
480
481
0
static inline uint64_t CRYPTO_load_u64_le(const void *in) {
482
0
  uint64_t v;
483
0
  OPENSSL_memcpy(&v, in, sizeof(v));
484
#if defined(RING_BIG_ENDIAN)
485
  return CRYPTO_bswap8(v);
486
#else
487
0
  return v;
488
0
#endif
489
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_load_u64_le
Unexecuted instantiation: aes_nohw.c:CRYPTO_load_u64_le
Unexecuted instantiation: montgomery.c:CRYPTO_load_u64_le
Unexecuted instantiation: montgomery_inv.c:CRYPTO_load_u64_le
Unexecuted instantiation: gfp_p384.c:CRYPTO_load_u64_le
Unexecuted instantiation: limbs.c:CRYPTO_load_u64_le
Unexecuted instantiation: mem.c:CRYPTO_load_u64_le
Unexecuted instantiation: cpu_intel.c:CRYPTO_load_u64_le
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_load_u64_le
Unexecuted instantiation: poly1305_vec.c:CRYPTO_load_u64_le
Unexecuted instantiation: p256-nistz.c:CRYPTO_load_u64_le
Unexecuted instantiation: ecp_nistz.c:CRYPTO_load_u64_le
490
491
0
static inline void CRYPTO_store_u64_le(void *out, uint64_t v) {
492
#if defined(RING_BIG_ENDIAN)
493
  v = CRYPTO_bswap8(v);
494
#endif
495
0
  OPENSSL_memcpy(out, &v, sizeof(v));
496
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_store_u64_le
Unexecuted instantiation: aes_nohw.c:CRYPTO_store_u64_le
Unexecuted instantiation: montgomery.c:CRYPTO_store_u64_le
Unexecuted instantiation: montgomery_inv.c:CRYPTO_store_u64_le
Unexecuted instantiation: gfp_p384.c:CRYPTO_store_u64_le
Unexecuted instantiation: limbs.c:CRYPTO_store_u64_le
Unexecuted instantiation: mem.c:CRYPTO_store_u64_le
Unexecuted instantiation: cpu_intel.c:CRYPTO_store_u64_le
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_store_u64_le
Unexecuted instantiation: poly1305_vec.c:CRYPTO_store_u64_le
Unexecuted instantiation: p256-nistz.c:CRYPTO_store_u64_le
Unexecuted instantiation: ecp_nistz.c:CRYPTO_store_u64_le
497
498
0
static inline uint64_t CRYPTO_load_u64_be(const void *ptr) {
499
0
  uint64_t ret;
500
0
  OPENSSL_memcpy(&ret, ptr, sizeof(ret));
501
0
#if !defined(RING_BIG_ENDIAN)
502
0
  return CRYPTO_bswap8(ret);
503
0
#else
504
0
  return ret;
505
0
#endif
506
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_load_u64_be
Unexecuted instantiation: aes_nohw.c:CRYPTO_load_u64_be
Unexecuted instantiation: montgomery.c:CRYPTO_load_u64_be
Unexecuted instantiation: montgomery_inv.c:CRYPTO_load_u64_be
Unexecuted instantiation: gfp_p384.c:CRYPTO_load_u64_be
Unexecuted instantiation: limbs.c:CRYPTO_load_u64_be
Unexecuted instantiation: mem.c:CRYPTO_load_u64_be
Unexecuted instantiation: cpu_intel.c:CRYPTO_load_u64_be
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_load_u64_be
Unexecuted instantiation: poly1305_vec.c:CRYPTO_load_u64_be
Unexecuted instantiation: p256-nistz.c:CRYPTO_load_u64_be
Unexecuted instantiation: ecp_nistz.c:CRYPTO_load_u64_be
507
508
0
static inline void CRYPTO_store_u64_be(void *out, uint64_t v) {
509
0
#if !defined(RING_BIG_ENDIAN)
510
0
  v = CRYPTO_bswap8(v);
511
0
#endif
512
0
  OPENSSL_memcpy(out, &v, sizeof(v));
513
0
}
Unexecuted instantiation: curve25519.c:CRYPTO_store_u64_be
Unexecuted instantiation: aes_nohw.c:CRYPTO_store_u64_be
Unexecuted instantiation: montgomery.c:CRYPTO_store_u64_be
Unexecuted instantiation: montgomery_inv.c:CRYPTO_store_u64_be
Unexecuted instantiation: gfp_p384.c:CRYPTO_store_u64_be
Unexecuted instantiation: limbs.c:CRYPTO_store_u64_be
Unexecuted instantiation: mem.c:CRYPTO_store_u64_be
Unexecuted instantiation: cpu_intel.c:CRYPTO_store_u64_be
Unexecuted instantiation: curve25519_64_adx.c:CRYPTO_store_u64_be
Unexecuted instantiation: poly1305_vec.c:CRYPTO_store_u64_be
Unexecuted instantiation: p256-nistz.c:CRYPTO_store_u64_be
Unexecuted instantiation: ecp_nistz.c:CRYPTO_store_u64_be
514
515
516
// Runtime CPU feature support
517
518
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
519
// OPENSSL_ia32cap_P contains the Intel CPUID bits when running on an x86 or
520
// x86-64 system.
521
//
522
//   Index 0:
523
//     EDX for CPUID where EAX = 1
524
//     Bit 20 is always zero
525
//     Bit 28 is adjusted to reflect whether the data cache is shared between
526
//       multiple logical cores
527
//     Bit 30 is used to indicate an Intel CPU
528
//   Index 1:
529
//     ECX for CPUID where EAX = 1
530
//     Bit 11 is used to indicate AMD XOP support, not SDBG
531
//   Index 2:
532
//     EBX for CPUID where EAX = 7
533
//   Index 3:
534
//     ECX for CPUID where EAX = 7
535
//
536
// Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM
537
// bits in XCR0, so it is not necessary to check those.
538
extern uint32_t OPENSSL_ia32cap_P[4];
539
#endif
540
541
#endif  // OPENSSL_HEADER_CRYPTO_INTERNAL_H