/src/spdm-rs/external/ring/crypto/fipsmodule/bn/internal.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | // you may not use this file except in compliance with the License. |
6 | | // You may obtain a copy of the License at |
7 | | // |
8 | | // https://www.apache.org/licenses/LICENSE-2.0 |
9 | | // |
10 | | // Unless required by applicable law or agreed to in writing, software |
11 | | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | // See the License for the specific language governing permissions and |
14 | | // limitations under the License. |
15 | | |
16 | | #ifndef OPENSSL_HEADER_BN_INTERNAL_H |
17 | | #define OPENSSL_HEADER_BN_INTERNAL_H |
18 | | |
19 | | #include <ring-core/base.h> |
20 | | |
21 | | #if defined(OPENSSL_X86_64) && defined(_MSC_VER) && !defined(__clang__) |
22 | | #pragma warning(push, 3) |
23 | | #include <intrin.h> |
24 | | #pragma warning(pop) |
25 | | #pragma intrinsic(_umul128) |
26 | | #endif |
27 | | |
28 | | #include "../../internal.h" |
29 | | |
30 | | typedef crypto_word_t BN_ULONG; |
31 | | |
32 | | #if defined(OPENSSL_64_BIT) |
33 | | |
34 | | #if defined(BORINGSSL_HAS_UINT128) |
35 | | // MSVC doesn't support two-word integers on 64-bit. |
36 | 0 | #define BN_ULLONG uint128_t |
37 | | #endif |
38 | | |
39 | 0 | #define BN_BITS2 64 |
40 | 0 | #define BN_MONT_CTX_N0_LIMBS 1 |
41 | | #define BN_MONT_CTX_N0(hi, lo) TOBN(hi, lo), 0 |
42 | | #define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo)) |
43 | | |
44 | | #elif defined(OPENSSL_32_BIT) |
45 | | |
46 | | #define BN_ULLONG uint64_t |
47 | | #define BN_BITS2 32 |
48 | | // On some 32-bit platforms, Montgomery multiplication is done using 64-bit |
49 | | // arithmetic with SIMD instructions. On such platforms, |BN_MONT_CTX::n0| |
50 | | // needs to be two words long. Only certain 32-bit platforms actually make use |
51 | | // of n0[1] and shorter R value would suffice for the others. However, |
52 | | // currently only the assembly files know which is which. |
53 | | #define BN_MONT_CTX_N0_LIMBS 2 |
54 | | #define BN_MONT_CTX_N0(hi, lo) TOBN(hi, lo) |
55 | | #define TOBN(hi, lo) (lo), (hi) |
56 | | |
57 | | #else |
58 | | #error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" |
59 | | #endif |
60 | | |
61 | | |
62 | | |
63 | | // BN_MONTGOMERY_MAX_WORDS is the maximum numer of words allowed in a |BIGNUM| |
64 | | // used with Montgomery reduction. Ideally this limit would be applied to all |
65 | | // |BIGNUM|s, in |bn_wexpand|, but the exactfloat library needs to create 8 MiB |
66 | | // values for other operations. |
67 | | // #define BN_MONTGOMERY_MAX_WORDS (8 * 1024 / sizeof(BN_ULONG)) |
68 | | |
69 | | // bn_mul_mont writes |ap| * |bp| mod |np| to |rp|, each |num| words |
70 | | // long. Inputs and outputs are in Montgomery form. |n0| is a pointer to |
71 | | // an |N0|. |
72 | | // |
73 | | // If at least one of |ap| or |bp| is fully reduced, |rp| will be fully reduced. |
74 | | // If neither is fully-reduced, the output may not be either. |
75 | | // |
76 | | // This function allocates |num| words on the stack, so |num| should be at most |
77 | | // |BN_MONTGOMERY_MAX_WORDS|. |
78 | | // |
79 | | // TODO(davidben): The x86_64 implementation expects a 32-bit input and masks |
80 | | // off upper bits. The aarch64 implementation expects a 64-bit input and does |
81 | | // not. |size_t| is the safer option but not strictly correct for x86_64. But |
82 | | // the |BN_MONTGOMERY_MAX_WORDS| bound makes this moot. |
83 | | // |
84 | | // See also discussion in |ToWord| in abi_test.h for notes on smaller-than-word |
85 | | // inputs. |
86 | | // |
87 | | // |num| must be at least 4, at least on x86. |
88 | | // |
89 | | // In other forks, |bn_mul_mont| returns an |int| indicating whether it |
90 | | // actually did the multiplication. All our implementations always do the |
91 | | // multiplication, and forcing callers to deal with the possibility of it |
92 | | // failing just leads to further problems. |
93 | | OPENSSL_STATIC_ASSERT(sizeof(int) == sizeof(size_t) || |
94 | | (sizeof(int) == 4 && sizeof(size_t) == 8), |
95 | | "int and size_t ABI mismatch"); |
96 | | #if defined(OPENSSL_X86_64) |
97 | | void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
98 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num); |
99 | | static inline void bn_mul_mont_small( |
100 | | BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
101 | 0 | const BN_ULONG *np, const BN_ULONG *n0, size_t num) { |
102 | 0 | bn_mul_mont_nohw(rp, ap, bp, np, n0, num); |
103 | 0 | } Unexecuted instantiation: montgomery_inv.c:bn_mul_mont_small Unexecuted instantiation: gfp_p384.c:bn_mul_mont_small Unexecuted instantiation: limbs.c:bn_mul_mont_small Unexecuted instantiation: p256-nistz.c:bn_mul_mont_small Unexecuted instantiation: montgomery.c:bn_mul_mont_small |
104 | | #elif defined(OPENSSL_AARCH64) |
105 | | void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
106 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num); |
107 | | static inline void bn_mul_mont_small( |
108 | | BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
109 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num) { |
110 | | // No point in optimizing for P-256 because P-256 doesn't call into |
111 | | // this on AArch64. |
112 | | bn_mul_mont_nohw(rp, ap, bp, np, n0, num); |
113 | | } |
114 | | #elif defined(OPENSSL_ARM) |
115 | | void bn_mul8x_mont_neon(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
116 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num); |
117 | | void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
118 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num); |
119 | | static inline void bn_mul_mont_small( |
120 | | BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
121 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num) { |
122 | | // Approximate what `bn_mul_mont` did so that the NEON version for P-256 |
123 | | // when practical. |
124 | | if (num == 8) { |
125 | | // XXX: This should not be accessing `neon_available` directly. |
126 | | if (neon_available) { |
127 | | bn_mul8x_mont_neon(rp, ap, bp, np, n0, num); |
128 | | return; |
129 | | } |
130 | | } |
131 | | bn_mul_mont_nohw(rp, ap, bp, np, n0, num); |
132 | | } |
133 | | #else |
134 | | void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
135 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num); |
136 | | static inline void bn_mul_mont_small( |
137 | | BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, |
138 | | const BN_ULONG *np, const BN_ULONG *n0, size_t num) { |
139 | | bn_mul_mont(rp, ap, bp, np, n0, num); |
140 | | } |
141 | | #endif |
142 | | |
143 | | static inline void bn_umult_lohi(BN_ULONG *low_out, BN_ULONG *high_out, |
144 | 0 | BN_ULONG a, BN_ULONG b) { |
145 | | #if defined(OPENSSL_X86_64) && defined(_MSC_VER) && !defined(__clang__) |
146 | | *low_out = _umul128(a, b, high_out); |
147 | | #else |
148 | 0 | BN_ULLONG result = (BN_ULLONG)a * b; |
149 | 0 | *low_out = (BN_ULONG)result; |
150 | 0 | *high_out = (BN_ULONG)(result >> BN_BITS2); |
151 | 0 | #endif |
152 | 0 | } Unexecuted instantiation: montgomery_inv.c:bn_umult_lohi Unexecuted instantiation: gfp_p384.c:bn_umult_lohi Unexecuted instantiation: limbs.c:bn_umult_lohi Unexecuted instantiation: p256-nistz.c:bn_umult_lohi Unexecuted instantiation: montgomery.c:bn_umult_lohi |
153 | | |
154 | | #endif // OPENSSL_HEADER_BN_INTERNAL_H |