Coverage Report

Created: 2024-11-21 07:03

/src/SymCrypt/lib/ec_dispatch.c
Line
Count
Source (jump to first uncovered line)
1
//
2
// ec_dispatch.c   Dispatch file for elliptic curve crypto functions
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
//
7
8
#include "precomp.h"
9
10
// Table with all the pointers to SYMCRYPT_ECURVE_FUNCTIONS
11
const SYMCRYPT_ECURVE_FUNCTIONS SymCryptEcurveDispatchTable[] =
12
{
13
    // NULL Type
14
    {
15
        NULL,       // SymCryptEcpointSetZeroNotImplemented,
16
        NULL,       // SymCryptEcpointSetDistinguishedPointNotImplemented,
17
        NULL,       // SymCryptEcpointSetRandomNotImplemented,
18
        NULL,       // SymCryptEcpointIsEqualNotImplemented,
19
        NULL,       // SymCryptEcpointIsZeroNotImplemented,
20
        NULL,       // SymCryptEcpointOnCurveNotImplemented,
21
        NULL,       // SymCryptEcpointAddNotImplemented,
22
        NULL,       // SymCryptEcpointAddDiffNonZeroNotImplemented,
23
        NULL,       // SymCryptEcpointDoubleNotImplemented,
24
        NULL,       // SymCryptEcpointNegateNotImplemented,
25
        NULL,       // SymCryptEcpointScalarMulNotImplemented,
26
        NULL,       // SymCryptEcpointMultiScalarMulNotImplemented,
27
    },
28
    // Short Weierstrass
29
    {
30
        SymCryptShortWeierstrassSetZero,
31
        SymCryptShortWeierstrassSetDistinguished,
32
        SymCryptEcpointGenericSetRandom,
33
        SymCryptShortWeierstrassIsEqual,
34
        SymCryptShortWeierstrassIsZero,
35
        SymCryptShortWeierstrassOnCurve,
36
        SymCryptShortWeierstrassAdd,
37
        SymCryptShortWeierstrassAddDiffNonZero,
38
        SymCryptShortWeierstrassDouble,
39
        SymCryptShortWeierstrassNegate,
40
        SymCryptEcpointScalarMulFixedWindow,
41
        SymCryptEcpointMultiScalarMulWnafWithInterleaving,
42
    },
43
    // Twisted Edwards
44
    {
45
        SymCryptTwistedEdwardsSetZero,
46
        SymCryptTwistedEdwardsSetDistinguished,
47
        SymCryptEcpointGenericSetRandom,
48
        SymCryptTwistedEdwardsIsEqual,
49
        SymCryptTwistedEdwardsIsZero,
50
        SymCryptTwistedEdwardsOnCurve,
51
        SymCryptTwistedEdwardsAdd,
52
        SymCryptTwistedEdwardsAddDiffNonZero,
53
        SymCryptTwistedEdwardsDouble,
54
        SymCryptTwistedEdwardsNegate,
55
        SymCryptEcpointScalarMulFixedWindow,
56
        SymCryptEcpointMultiScalarMulWnafWithInterleaving,
57
    },
58
    // Montgomery
59
    {
60
        NULL,       // SymCryptEcpointSetZeroNotImplemented,
61
        SymCryptMontgomerySetDistinguished,
62
        SymCryptEcpointGenericSetRandom,
63
        SymCryptMontgomeryIsEqual,
64
        SymCryptMontgomeryIsZero,
65
        NULL,       // SymCryptEcpointOnCurveNotImplemented,
66
        NULL,       // SymCryptEcpointAddNotImplemented,
67
        NULL,       // SymCryptEcpointAddDiffNonZeroNotImplemented,
68
        NULL,       // SymCryptEcpointDoubleNotImplemented,
69
        NULL,       // SymCryptEcpointNegateNotImplemented,
70
        SymCryptMontgomeryPointScalarMul,
71
        NULL,       // SymCryptEcpointMultiScalarMulNotImplemented,
72
    },
73
    // Short Weierstrass with A==-3
74
    {
75
        SymCryptShortWeierstrassSetZero,
76
        SymCryptShortWeierstrassSetDistinguished,
77
        SymCryptEcpointGenericSetRandom,
78
        SymCryptShortWeierstrassIsEqual,
79
        SymCryptShortWeierstrassIsZero,
80
        SymCryptShortWeierstrassOnCurve,
81
        SymCryptShortWeierstrassAdd,
82
        SymCryptShortWeierstrassAddDiffNonZero,
83
        SymCryptShortWeierstrassDoubleSpecializedAm3,
84
        SymCryptShortWeierstrassNegate,
85
        SymCryptEcpointScalarMulFixedWindow,
86
        SymCryptEcpointMultiScalarMulWnafWithInterleaving,
87
    },
88
    // Slack to make dispatch table size a power of 2
89
    {NULL,},
90
    {NULL,},
91
    {NULL,},
92
};
93
94
553k
#define SYMCRYPT_ECURVE_DISPATCH_TABLE_SIZE (sizeof( SymCryptEcurveDispatchTable ))
95
96
// Ensure the table size is a power of 2
97
C_ASSERT( (SYMCRYPT_ECURVE_DISPATCH_TABLE_SIZE & (SYMCRYPT_ECURVE_DISPATCH_TABLE_SIZE - 1)) == 0 );
98
99
// For now the ECurve type encodes the index into this dispatch table, so we just mask by the size of the table
100
//
101
// We could instead encode the absolute offset into the table in the type field (similar to the Modulus dispatch table),
102
// and this mask would be multiplied by SYMCRYPT_ECURVE_FUNCTIONS_SIZE
103
553k
#define SYMCRYPT_ECURVE_DISPATCH_TABLE_MASK ((SYMCRYPT_ECURVE_DISPATCH_TABLE_SIZE / SYMCRYPT_ECURVE_FUNCTIONS_SIZE)-1)
104
105
// We mask to constrain the unpredictable behaviour in the case of memory corruption; we do not want to interpret some data
106
// beyond the end of the dispatch table as function pointers
107
553k
#define SYMCRYPT_ECURVE_CALL(v) (SymCryptEcurveDispatchTable[SYMCRYPT_FORCE_READ32(&(v)->type) & SYMCRYPT_ECURVE_DISPATCH_TABLE_MASK]).
108
109
// We read the curve's internal type with a 32b read so it must be 4 bytes large
110
C_ASSERT(sizeof(((PCSYMCRYPT_ECURVE)0)->type) == 4);
111
112
// Main functions
113
SYMCRYPT_DISABLE_CFG
114
VOID
115
SYMCRYPT_CALL
116
SymCryptEcpointSetZero(
117
    _In_    PCSYMCRYPT_ECURVE   pCurve,
118
    _Out_   PSYMCRYPT_ECPOINT   poDst,
119
    _Out_writes_bytes_opt_( cbScratch )
120
            PBYTE               pbScratch,
121
            SIZE_T              cbScratch )
122
986
{
123
986
    SYMCRYPT_ECURVE_CALL( pCurve ) setZeroFunc( pCurve, poDst, pbScratch, cbScratch );
124
986
}
125
126
SYMCRYPT_DISABLE_CFG
127
VOID
128
SYMCRYPT_CALL
129
SymCryptEcpointSetDistinguishedPoint(
130
    _In_    PCSYMCRYPT_ECURVE   pCurve,
131
    _Out_   PSYMCRYPT_ECPOINT   poDst,
132
    _Out_writes_bytes_opt_( cbScratch )
133
            PBYTE               pbScratch,
134
            SIZE_T              cbScratch )
135
0
{
136
0
    SYMCRYPT_ECURVE_CALL( pCurve ) setDistinguishedFunc( pCurve, poDst, pbScratch, cbScratch );
137
0
}
138
139
SYMCRYPT_DISABLE_CFG
140
VOID
141
SYMCRYPT_CALL
142
SymCryptEcpointSetRandom(
143
    _In_    PCSYMCRYPT_ECURVE       pCurve,
144
    _Out_   PSYMCRYPT_INT           piScalar,
145
    _Out_   PSYMCRYPT_ECPOINT       poDst,
146
    _Out_writes_bytes_opt_( cbScratch )
147
            PBYTE                   pbScratch,
148
            SIZE_T                  cbScratch )
149
0
{
150
0
    SYMCRYPT_ECURVE_CALL( pCurve ) setRandomFunc( pCurve, piScalar, poDst, pbScratch, cbScratch );
151
0
}
152
153
SYMCRYPT_DISABLE_CFG
154
UINT32
155
SYMCRYPT_CALL
156
SymCryptEcpointIsEqual(
157
    _In_    PCSYMCRYPT_ECURVE   pCurve,
158
    _In_    PCSYMCRYPT_ECPOINT  poSrc1,
159
    _In_    PCSYMCRYPT_ECPOINT  poSrc2,
160
            UINT32              flags,
161
    _Out_writes_bytes_opt_( cbScratch )
162
            PBYTE               pbScratch,
163
            SIZE_T              cbScratch )
164
0
{
165
0
    return SYMCRYPT_ECURVE_CALL( pCurve ) isEqualFunc( pCurve, poSrc1, poSrc2, flags, pbScratch, cbScratch );
166
0
}
167
168
SYMCRYPT_DISABLE_CFG
169
UINT32
170
SYMCRYPT_CALL
171
SymCryptEcpointIsZero(
172
    _In_    PCSYMCRYPT_ECURVE   pCurve,
173
    _In_    PCSYMCRYPT_ECPOINT  poSrc,
174
    _Out_writes_bytes_opt_( cbScratch )
175
            PBYTE               pbScratch,
176
            SIZE_T              cbScratch )
177
3.23k
{
178
3.23k
    return SYMCRYPT_ECURVE_CALL( pCurve ) isZeroFunc( pCurve, poSrc, pbScratch, cbScratch );
179
3.23k
}
180
181
SYMCRYPT_DISABLE_CFG
182
UINT32
183
SYMCRYPT_CALL
184
SymCryptEcpointOnCurve(
185
    _In_    PCSYMCRYPT_ECURVE   pCurve,
186
    _In_    PCSYMCRYPT_ECPOINT  poSrc,
187
    _Out_writes_bytes_opt_( cbScratch )
188
            PBYTE               pbScratch,
189
            SIZE_T              cbScratch )
190
816
{
191
816
    return SYMCRYPT_ECURVE_CALL( pCurve ) onCurveFunc( pCurve, poSrc, pbScratch, cbScratch );
192
816
}
193
194
SYMCRYPT_DISABLE_CFG
195
VOID
196
SYMCRYPT_CALL
197
SymCryptEcpointAdd(
198
    _In_    PCSYMCRYPT_ECURVE   pCurve,
199
    _In_    PCSYMCRYPT_ECPOINT  poSrc1,
200
    _In_    PCSYMCRYPT_ECPOINT  poSrc2,
201
    _Out_   PSYMCRYPT_ECPOINT   poDst,
202
            UINT32              flags,
203
    _Out_writes_bytes_opt_( cbScratch )
204
            PBYTE               pbScratch,
205
            SIZE_T              cbScratch )
206
21.1k
{
207
21.1k
    SYMCRYPT_ECURVE_CALL( pCurve ) addFunc( pCurve, poSrc1, poSrc2, poDst, flags, pbScratch, cbScratch );
208
21.1k
}
209
210
SYMCRYPT_DISABLE_CFG
211
VOID
212
SYMCRYPT_CALL
213
SymCryptEcpointAddDiffNonZero(
214
    _In_    PCSYMCRYPT_ECURVE   pCurve,
215
    _In_    PCSYMCRYPT_ECPOINT  poSrc1,
216
    _In_    PCSYMCRYPT_ECPOINT  poSrc2,
217
    _Out_   PSYMCRYPT_ECPOINT   poDst,
218
    _Out_writes_bytes_opt_( cbScratch )
219
            PBYTE               pbScratch,
220
            SIZE_T              cbScratch )
221
77.0k
{
222
77.0k
    SYMCRYPT_ECURVE_CALL( pCurve ) addDiffFunc( pCurve, poSrc1, poSrc2, poDst, pbScratch, cbScratch );
223
77.0k
}
224
225
SYMCRYPT_DISABLE_CFG
226
VOID
227
SYMCRYPT_CALL
228
SymCryptEcpointDouble(
229
    _In_    PCSYMCRYPT_ECURVE   pCurve,
230
    _In_    PCSYMCRYPT_ECPOINT  poSrc,
231
    _Out_   PSYMCRYPT_ECPOINT   poDst,
232
            UINT32              flags,
233
    _Out_writes_bytes_opt_( cbScratch )
234
            PBYTE               pbScratch,
235
            SIZE_T              cbScratch )
236
378k
{
237
378k
    SYMCRYPT_ECURVE_CALL( pCurve ) doubleFunc( pCurve, poSrc, poDst, flags, pbScratch, cbScratch );
238
378k
}
239
240
SYMCRYPT_DISABLE_CFG
241
VOID
242
SYMCRYPT_CALL
243
SymCryptEcpointNegate(
244
    _In_    PCSYMCRYPT_ECURVE   pCurve,
245
    _Inout_ PSYMCRYPT_ECPOINT   poSrc,
246
            UINT32              mask,
247
    _Out_writes_bytes_opt_( cbScratch )
248
            PBYTE               pbScratch,
249
            SIZE_T              cbScratch )
250
70.4k
{
251
70.4k
    SYMCRYPT_ECURVE_CALL( pCurve ) negateFunc( pCurve, poSrc, mask, pbScratch, cbScratch );
252
70.4k
}
253
254
SYMCRYPT_DISABLE_CFG
255
SYMCRYPT_ERROR
256
SYMCRYPT_CALL
257
SymCryptEcpointScalarMul(
258
    _In_    PCSYMCRYPT_ECURVE   pCurve,
259
    _In_    PCSYMCRYPT_INT      piScalar,
260
    _In_opt_
261
            PCSYMCRYPT_ECPOINT  poSrc,
262
            UINT32              flags,
263
    _Out_   PSYMCRYPT_ECPOINT   poDst,
264
    _Out_writes_bytes_opt_( cbScratch )
265
            PBYTE               pbScratch,
266
            SIZE_T              cbScratch )
267
795
{
268
795
    return SYMCRYPT_ECURVE_CALL( pCurve ) scalarMulFunc( pCurve, piScalar, poSrc, flags, poDst, pbScratch, cbScratch );
269
795
}
270
271
SYMCRYPT_DISABLE_CFG
272
SYMCRYPT_ERROR
273
SYMCRYPT_CALL
274
SymCryptEcpointMultiScalarMul(
275
    _In_    PCSYMCRYPT_ECURVE       pCurve,
276
    _In_    PCSYMCRYPT_INT *        piSrcScalarArray,
277
    _In_    PCSYMCRYPT_ECPOINT *    poSrcEcpointArray,
278
            UINT32                  nPoints,
279
            UINT32                  flags,
280
    _Out_   PSYMCRYPT_ECPOINT       poDst,
281
    _Out_writes_bytes_opt_( cbScratch )
282
            PBYTE                   pbScratch,
283
            SIZE_T                  cbScratch )
284
191
{
285
191
    return SYMCRYPT_ECURVE_CALL( pCurve ) multiScalarMulFunc( pCurve, piSrcScalarArray, poSrcEcpointArray, nPoints, flags, poDst, pbScratch, cbScratch );
286
191
}