Coverage Report

Created: 2025-08-25 06:27

/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