Coverage Report

Created: 2023-09-25 06:15

/src/ibmswtpm2/src/TpmToOsslMath.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*       TPM to OpenSSL BigNum Shim Layer     */
4
/*           Written by Ken Goldman       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*            $Id: TpmToOsslMath.c 1314 2018-08-28 14:25:12Z kgoldman $   */
7
/*                    */
8
/*  Licenses and Notices              */
9
/*                    */
10
/*  1. Copyright Licenses:              */
11
/*                    */
12
/*  - Trusted Computing Group (TCG) grants to the user of the source code in  */
13
/*    this specification (the "Source Code") a worldwide, irrevocable,    */
14
/*    nonexclusive, royalty free, copyright license to reproduce, create  */
15
/*    derivative works, distribute, display and perform the Source Code and */
16
/*    derivative works thereof, and to grant others the rights granted herein.  */
17
/*                    */
18
/*  - The TCG grants to the user of the other parts of the specification  */
19
/*    (other than the Source Code) the rights to reproduce, distribute,   */
20
/*    display, and perform the specification solely for the purpose of    */
21
/*    developing products based on such documents.        */
22
/*                    */
23
/*  2. Source Code Distribution Conditions:         */
24
/*                    */
25
/*  - Redistributions of Source Code must retain the above copyright licenses,  */
26
/*    this list of conditions and the following disclaimers.      */
27
/*                    */
28
/*  - Redistributions in binary form must reproduce the above copyright   */
29
/*    licenses, this list of conditions and the following disclaimers in the  */
30
/*    documentation and/or other materials provided with the distribution.  */
31
/*                    */
32
/*  3. Disclaimers:               */
33
/*                    */
34
/*  - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35
/*  LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36
/*  RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37
/*  THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE.   */
38
/*  Contact TCG Administration (admin@trustedcomputinggroup.org) for    */
39
/*  information on specification licensing rights available through TCG   */
40
/*  membership agreements.              */
41
/*                    */
42
/*  - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED   */
43
/*    WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR   */
44
/*    FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR    */
45
/*    NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY    */
46
/*    OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE.   */
47
/*                    */
48
/*  - Without limitation, TCG and its members and licensors disclaim all  */
49
/*    liability, including liability for infringement of any proprietary  */
50
/*    rights, relating to use of information in this specification and to the */
51
/*    implementation of this specification, and TCG disclaims all liability for */
52
/*    cost of procurement of substitute goods or services, lost profits, loss   */
53
/*    of use, loss of data or any incidental, consequential, direct, indirect,  */
54
/*    or special damages, whether under contract, tort, warranty or otherwise,  */
55
/*    arising in any way out of use or reliance upon this specification or any  */
56
/*    information herein.             */
57
/*                    */
58
/*  (c) Copyright IBM Corp. and others, 2016 - 2018       */
59
/*                    */
60
/********************************************************************************/
61
62
/* B.2.3.2. TpmToOsslMath.c */
63
/* B.2.3.2.1. Introduction */
64
/* This file contains the math functions that are not implemented in the BnMath() library
65
   (yet). These math functions will call the OpenSSL() library to execute the operations. There is a
66
   difference between the internal format and the OpenSSL() format. To call the OpenSSL() function,
67
   a BIGNUM structure is created for each passed variable. The sizes in the bignum_t are copied and
68
   the d pointer in the BIGNUM is set to point to the d parameter of the bignum_t. On return,
69
   SetSizeOsslToTpm() is used for each returned variable to make sure that the pointers are not
70
   changed. The size of the returned BIGGNUM is copied to bignum_t. */
71
/* B.2.3.2.2. Includes and Defines */
72
#include "Tpm.h"
73
#if MATH_LIB == OSSL
74
#include "TpmToOsslMath_fp.h"
75
/* B.2.3.2.3.1. OsslToTpmBn() */
76
/* This function converts an OpenSSL() BIGNUM to a TPM bignum. In this implementation it is assumed
77
   that OpenSSL() used the same format for a big number as does the TPM -- an array of native-endian
78
   words in little-endian order. */
79
/* If the array allocated for the OpenSSL() BIGNUM is not the space within the TPM bignum, then the
80
   data is copied. Otherwise, just the size field of the BIGNUM is copied. */
81
void
82
OsslToTpmBn(
83
      bigNum          bn,
84
      BIGNUM          *osslBn
85
      )
86
0
{
87
0
    unsigned char buffer[LARGEST_NUMBER + 1];
88
0
    int buffer_len;
89
90
0
    if(bn != NULL)
91
0
  {
92
0
      pAssert(BN_num_bytes(osslBn) >= 0);
93
0
      pAssert(sizeof(buffer) >= (size_t)BN_num_bytes(osslBn));
94
0
      buffer_len = BN_bn2bin(osslBn, buffer); /* ossl to bin */
95
0
      BnFromBytes(bn, buffer, buffer_len);  /* bin to TPM */
96
0
  }
97
0
}
98
/* B.2.3.2.3.2. BigInitialized() */
99
/* This function initializes an OSSL BIGNUM from a TPM bignum. */
100
BIGNUM *
101
BigInitialized(
102
         bigConst            initializer
103
         )
104
0
{
105
0
    BIGNUM *toInit = NULL;
106
0
    unsigned char buffer[LARGEST_NUMBER + 1];
107
0
    NUMBYTES buffer_len = (NUMBYTES )sizeof(buffer);
108
    
109
0
    if (initializer == NULL) {
110
0
  return NULL;
111
0
    }
112
0
    BnToBytes(initializer, buffer, &buffer_len);  /* TPM to bin */
113
0
    toInit = BN_bin2bn(buffer, buffer_len, NULL); /* bin to ossl */
114
0
    return toInit;
115
0
}
116
117
#ifndef OSSL_DEBUG
118
#   define BIGNUM_PRINT(label, bn, eol)
119
#   define DEBUG_PRINT(x)
120
#else
121
#   define DEBUG_PRINT(x)   printf("%s", x)
122
#   define BIGNUM_PRINT(label, bn, eol) BIGNUM_print((label), (bn), (eol))
123
static
124
void BIGNUM_print(
125
      const char      *label,
126
      const BIGNUM    *a,
127
      BOOL             eol
128
      )
129
{
130
    BN_ULONG        *d;
131
    int              i;
132
    int              notZero = FALSE;
133
    if(label != NULL)
134
  printf("%s", label);
135
    if(a == NULL)
136
  {
137
      printf("NULL");
138
      goto done;
139
  }
140
    if (a->neg)
141
  printf("-");
142
    for(i = a->top, d = &a->d[i - 1]; i > 0; i--)
143
  {
144
      int         j;
145
      BN_ULONG    l = *d--;
146
      for(j = BN_BITS2 - 8; j >= 0; j -= 8)
147
    {
148
        BYTE    b = (BYTE)((l >> j) & 0xFF);
149
        notZero = notZero || (b != 0);
150
        if(notZero)
151
      printf("%02x", b);
152
    }
153
      if(!notZero)
154
    printf("0");
155
  }
156
 done:
157
    if(eol)
158
  printf("\n");
159
    return;
160
}
161
#endif
162
#if LIBRARY_COMPATIBILITY_CHECK
163
void
164
MathLibraryCompatibilityCheck(
165
            void
166
            )
167
{
168
    OSSL_ENTER();
169
    BIGNUM          *osslTemp = BN_CTX_get(CTX);
170
    BN_VAR(tpmTemp, 64 * 8); // allocate some space for a test value
171
    crypt_uword_t           i;
172
    TPM2B_TYPE(TEST, 16);
173
    TPM2B_TEST              test = {{16, {0x0F, 0x0E, 0x0D, 0x0C,
174
            0x0B, 0x0A, 0x09, 0x08,
175
            0x07, 0x06, 0x05, 0x04,
176
            0x03, 0x02, 0x01, 0x00}}};
177
    // Convert the test TPM2B to a bigNum
178
    BnFrom2B(tpmTemp, &test.b);
179
    // Convert the test TPM2B to an OpenSSL BIGNUM
180
    BN_bin2bn(test.t.buffer, test.t.size, osslTemp);
181
    // Make sure the values are consistent
182
    cAssert(osslTemp->top == (int)tpmTemp->size);
183
    for(i = 0; i < tpmTemp->size; i++)
184
  cAssert(osslTemp->d[0] == tpmTemp->d[0]);
185
    OSSL_LEAVE();
186
}
187
#endif
188
/* B.2.3.2.3.2. BnModMult() */
189
/* Does multiply and divide returning the remainder of the divide. */
190
LIB_EXPORT BOOL
191
BnModMult(
192
    bigNum              result,
193
    bigConst            op1,
194
    bigConst            op2,
195
    bigConst            modulus
196
    )
197
0
{
198
0
    OSSL_ENTER();
199
0
    BIG_INITIALIZED(bnResult, result);
200
0
    BIG_INITIALIZED(bnOp1, op1);
201
0
    BIG_INITIALIZED(bnOp2, op2);
202
0
    BIG_INITIALIZED(bnMod, modulus);
203
0
    BIG_VAR(bnTemp, (LARGEST_NUMBER_BITS * 4));
204
0
    BOOL                OK;
205
0
    pAssert(BnGetAllocated(result) >= BnGetSize(modulus));
206
0
    OK = BN_mul(bnTemp, bnOp1, bnOp2, CTX);
207
0
    OK = OK && BN_div(NULL, bnResult, bnTemp, bnMod, CTX);
208
0
    if(OK)
209
0
  {
210
0
      result->size = DIV_UP(BN_num_bytes(bnResult),
211
0
                                  sizeof(crypt_uword_t));
212
0
      OsslToTpmBn(result, bnResult);
213
0
  }
214
0
    BN_free(bnTemp);
215
0
    BN_free(bnMod);
216
0
    BN_free(bnOp2);
217
0
    BN_free(bnOp1);
218
0
    BN_free(bnResult);
219
0
    OSSL_LEAVE();
220
0
    return OK;
221
0
}
222
/* B.2.3.2.3.3. BnMult() */
223
/* Multiplies two numbers */
224
LIB_EXPORT BOOL
225
BnMult(
226
       bigNum               result,
227
       bigConst             multiplicand,
228
       bigConst             multiplier
229
       )
230
0
{
231
0
    OSSL_ENTER();
232
0
    BN_VAR(temp, (LARGEST_NUMBER_BITS * 2));
233
0
    BIG_INITIALIZED(bnTemp, temp);
234
0
    BIG_INITIALIZED(bnA, multiplicand);
235
0
    BIG_INITIALIZED(bnB, multiplier);
236
0
    BOOL                OK;
237
0
    pAssert(result->allocated >=
238
0
      (BITS_TO_CRYPT_WORDS(BnSizeInBits(multiplicand)
239
0
         + BnSizeInBits(multiplier))));
240
0
    OK = BN_mul(bnTemp, bnA, bnB, CTX);
241
0
    if(OK)
242
0
  {
243
0
      OsslToTpmBn(temp, bnTemp);
244
0
      BnCopy(result, temp);
245
0
  }
246
0
    BN_free(bnB);
247
0
    BN_free(bnA);
248
0
    BN_free(bnTemp);
249
0
    OSSL_LEAVE();
250
0
    return OK;
251
0
}
252
/* B.2.3.2.3.4. BnDiv() */
253
/* This function divides two bigNum values. The function returns FALSE if there is an error in the
254
   operation. */
255
LIB_EXPORT BOOL
256
BnDiv(
257
      bigNum               quotient,
258
      bigNum               remainder,
259
      bigConst             dividend,
260
      bigConst             divisor
261
      )
262
0
{
263
0
    OSSL_ENTER();
264
0
    BIG_INITIALIZED(bnQ, quotient);
265
0
    BIG_INITIALIZED(bnR, remainder);
266
0
    BIG_INITIALIZED(bnDend, dividend);
267
0
    BIG_INITIALIZED(bnSor, divisor);
268
0
    BOOL        OK;
269
0
    pAssert(!BnEqualZero(divisor));
270
0
    if(BnGetSize(dividend) < BnGetSize(divisor))
271
0
  {
272
0
      if(quotient)
273
0
    BnSetWord(quotient, 0);
274
0
      if(remainder)
275
0
    BnCopy(remainder, dividend);
276
0
      OK = TRUE;
277
0
  }
278
0
    else
279
0
  {
280
0
      pAssert((quotient == NULL)
281
0
        || (quotient->allocated >= (unsigned)(dividend->size
282
0
                - divisor->size)));
283
0
      pAssert((remainder == NULL)
284
0
        || (remainder->allocated >= divisor->size));
285
0
      OK = BN_div(bnQ, bnR, bnDend, bnSor, CTX);
286
0
      if(OK)
287
0
    {
288
0
        OsslToTpmBn(quotient, bnQ);
289
0
        OsslToTpmBn(remainder, bnR);
290
0
    }
291
0
  }
292
0
    DEBUG_PRINT("In BnDiv:\n");
293
0
    BIGNUM_PRINT("   bnDividend: ", bnDend, TRUE);
294
0
    BIGNUM_PRINT("    bnDivisor: ", bnSor, TRUE);
295
0
    BIGNUM_PRINT("   bnQuotient: ", bnQ, TRUE);
296
0
    BIGNUM_PRINT("  bnRemainder: ", bnR, TRUE);
297
0
    BN_free(bnSor);
298
0
    BN_free(bnDend);
299
0
    BN_free(bnR);
300
0
    BN_free(bnQ);
301
0
    OSSL_LEAVE();
302
0
    return OK;
303
0
}
304
305
#if ALG_RSA
306
/* B.2.3.2.3.5. BnGcd() */
307
/* Get the greatest common divisor of two numbers */
308
LIB_EXPORT BOOL
309
BnGcd(
310
      bigNum      gcd,            // OUT: the common divisor
311
      bigConst    number1,        // IN:
312
      bigConst    number2         // IN:
313
      )
314
0
{
315
0
    OSSL_ENTER();
316
0
    BIG_INITIALIZED(bnGcd, gcd);
317
0
    BIG_INITIALIZED(bn1, number1);
318
0
    BIG_INITIALIZED(bn2, number2);
319
0
    BOOL            OK;
320
0
    pAssert(gcd != NULL);
321
0
    OK = BN_gcd(bnGcd, bn1, bn2, CTX);
322
0
    if(OK)
323
0
  {
324
0
      OsslToTpmBn(gcd, bnGcd);
325
0
      gcd->size = DIV_UP(BN_num_bytes(bnGcd), sizeof(crypt_uword_t));
326
0
  }
327
0
    BN_free(bn2);
328
0
    BN_free(bn1);
329
0
    BN_free(bnGcd);
330
0
    OSSL_LEAVE();
331
0
    return OK;
332
0
}
333
/* B.2.3.2.3.6. BnModExp() */
334
/* Do modular exponentiation using bigNum values. The conversion from a bignum_t to a bigNum is
335
   trivial as they are based on the same structure */
336
LIB_EXPORT BOOL
337
BnModExp(
338
   bigNum               result,         // OUT: the result
339
   bigConst             number,         // IN: number to exponentiate
340
   bigConst             exponent,       // IN:
341
   bigConst             modulus         // IN:
342
   )
343
0
{
344
0
    OSSL_ENTER();
345
0
    BIG_INITIALIZED(bnResult, result);
346
0
    BIG_INITIALIZED(bnN, number);
347
0
    BIG_INITIALIZED(bnE, exponent);
348
0
    BIG_INITIALIZED(bnM, modulus);
349
0
    BOOL            OK;
350
    //
351
0
    OK = BN_mod_exp(bnResult, bnN, bnE, bnM, CTX);
352
0
    if(OK)
353
0
  {
354
0
      OsslToTpmBn(result, bnResult);
355
0
  }
356
0
    BN_free(bnM);
357
0
    BN_free(bnE);
358
0
    BN_free(bnN);
359
0
    BN_free(bnResult);
360
0
    OSSL_LEAVE();
361
0
    return OK;
362
0
}
363
/* B.2.3.2.3.7. BnModInverse() */
364
/* Modular multiplicative inverse */
365
LIB_EXPORT BOOL
366
BnModInverse(
367
       bigNum               result,
368
       bigConst             number,
369
       bigConst             modulus
370
       )
371
0
{
372
0
    OSSL_ENTER();
373
0
    BIG_INITIALIZED(bnResult, result);
374
0
    BIG_INITIALIZED(bnN, number);
375
0
    BIG_INITIALIZED(bnM, modulus);
376
0
    BOOL                OK;
377
0
    OK = (BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL);
378
0
    if(OK)
379
0
  {
380
0
      OsslToTpmBn(result, bnResult);
381
0
  }
382
0
    BN_free(bnM);
383
0
    BN_free(bnN);
384
0
    BN_free(bnResult);
385
0
    OSSL_LEAVE();
386
0
    return OK;
387
0
}
388
#endif // TPM_ALG_RSA
389
390
#if ALG_ECC
391
/* B.2.3.2.3.8. PointFromOssl() */
392
/* Function to copy the point result from an OSSL function to a bigNum */
393
static BOOL
394
PointFromOssl(
395
        bigPoint         pOut,      // OUT: resulting point
396
        EC_POINT        *pIn,       // IN: the point to return
397
        bigCurve         E          // IN: the curve
398
        )
399
0
{
400
0
    BIGNUM         *x = NULL;
401
0
    BIGNUM         *y = NULL;
402
0
    BOOL            OK;
403
0
    BN_CTX_start(E->CTX);
404
    //
405
0
    x = BN_CTX_get(E->CTX);
406
0
    y = BN_CTX_get(E->CTX);
407
0
    if(y == NULL)
408
0
  FAIL(FATAL_ERROR_ALLOCATION);
409
    // If this returns false, then the point is at infinity
410
0
    OK = EC_POINT_get_affine_coordinates_GFp(E->G, pIn, x, y, E->CTX);
411
0
    if(OK)
412
0
  {
413
0
      OsslToTpmBn(pOut->x, x);
414
0
      OsslToTpmBn(pOut->y, y);
415
0
      BnSetWord(pOut->z, 1);
416
0
  }
417
0
    else
418
0
  BnSetWord(pOut->z, 0);
419
0
    BN_CTX_end(E->CTX);
420
0
    return OK;
421
0
}
422
/* B.2.3.2.3.9. EcPointInitialized() */
423
/* Allocate and initialize a point. */
424
static EC_POINT *
425
EcPointInitialized(
426
       pointConst          initializer,
427
       bigCurve            E
428
       )
429
0
{
430
0
    BIG_INITIALIZED(bnX, (initializer != NULL) ? initializer->x : NULL);
431
0
    BIG_INITIALIZED(bnY, (initializer != NULL) ? initializer->y : NULL);
432
0
    EC_POINT            *P = (initializer != NULL && E != NULL)
433
0
           ? EC_POINT_new(E->G) : NULL;
434
0
    pAssert(E != NULL);
435
0
    if(P != NULL)
436
0
  EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX);
437
0
    BN_free(bnY);
438
0
    BN_free(bnX);
439
0
    return P;
440
0
}
441
/* B.2.3.2.3.10. BnCurveInitialize() */
442
/* This function initializes the OpenSSL() group definition */
443
/* It is a fatal error if groupContext is not provided. */
444
/* Return Values Meaning */
445
/* NULL the TPM_ECC_CURVE is not valid */
446
/* non-NULL points to a structure in groupContext */
447
bigCurve
448
BnCurveInitialize(
449
      bigCurve          E,           // IN: curve structure to initialize
450
      TPM_ECC_CURVE     curveId      // IN: curve identifier
451
      )
452
0
{
453
0
    EC_GROUP                *group = NULL;
454
0
    EC_POINT                *P = NULL;
455
0
    const ECC_CURVE_DATA    *C = GetCurveData(curveId);
456
0
    BN_CTX                  *CTX = NULL;
457
0
    BIG_INITIALIZED(bnP, C != NULL ? C->prime : NULL);
458
0
    BIG_INITIALIZED(bnA, C != NULL ? C->a : NULL);
459
0
    BIG_INITIALIZED(bnB, C != NULL ? C->b : NULL);
460
0
    BIG_INITIALIZED(bnX, C != NULL ? C->base.x : NULL);
461
0
    BIG_INITIALIZED(bnY, C != NULL ? C->base.y : NULL);
462
0
    BIG_INITIALIZED(bnN, C != NULL ? C->order : NULL);
463
0
    BIG_INITIALIZED(bnH, C != NULL ? C->h : NULL);
464
0
    int                      OK = (C != NULL);
465
    //
466
0
    OK = OK && ((CTX = OsslContextEnter()) != NULL);
467
    // initialize EC group, associate a generator point and initialize the point
468
    // from the parameter data
469
    // Create a group structure
470
0
    OK = OK && (group = EC_GROUP_new_curve_GFp(bnP, bnA, bnB, CTX)) != NULL;
471
    // Allocate a point in the group that will be used in setting the
472
    // generator. This is not needed after the generator is set.
473
0
    OK = OK && ((P = EC_POINT_new(group)) != NULL);
474
    // Need to use this in case Montgomery method is being used
475
0
    OK = OK
476
0
   && EC_POINT_set_affine_coordinates_GFp(group, P, bnX, bnY, CTX);
477
    // Now set the generator
478
0
    OK = OK && EC_GROUP_set_generator(group, P, bnN, bnH);
479
0
    if(P != NULL)
480
0
  EC_POINT_free(P);
481
0
    if(!OK && group != NULL)
482
0
  {
483
0
      EC_GROUP_free(group);
484
0
      group = NULL;
485
0
  }
486
0
    if(!OK && CTX != NULL)
487
0
  {
488
0
      OsslContextLeave(CTX);
489
0
      CTX = NULL;
490
0
  }
491
0
    E->G = group;
492
0
    E->CTX = CTX;
493
0
    E->C = C;
494
0
    BN_free(bnH);
495
0
    BN_free(bnN);
496
0
    BN_free(bnY);
497
0
    BN_free(bnX);
498
0
    BN_free(bnB);
499
0
    BN_free(bnA);
500
0
    BN_free(bnP);
501
0
    return OK ? E : NULL;
502
0
}
503
/* B.2.3.2.3.11. BnEccModMult() */
504
/* This function does a point multiply of the form R = [d]S */
505
/* Return Values Meaning */
506
/* FALSE failure in operation; treat as result being point at infinity */
507
LIB_EXPORT BOOL
508
BnEccModMult(
509
       bigPoint             R,         // OUT: computed point
510
       pointConst           S,         // IN: point to multiply by 'd' (optional)
511
       bigConst             d,         // IN: scalar for [d]S
512
       bigCurve             E
513
       )
514
0
{
515
0
    EC_POINT            *pR = EC_POINT_new(E->G);
516
0
    EC_POINT            *pS = EcPointInitialized(S, E);
517
0
    BIG_INITIALIZED(bnD, d);
518
0
    if(S == NULL)
519
0
  EC_POINT_mul(E->G, pR, bnD, NULL, NULL, E->CTX);
520
0
    else
521
0
  EC_POINT_mul(E->G, pR, NULL, pS, bnD, E->CTX);
522
0
    PointFromOssl(R, pR, E);
523
0
    EC_POINT_free(pR);
524
0
    EC_POINT_free(pS);
525
0
    BN_free(bnD);
526
0
    return !BnEqualZero(R->z);
527
0
}
528
/* B.2.3.2.3.12. BnEccModMult2() */
529
/* This function does a point multiply of the form R = [d]G + [u]Q */
530
/* FALSE  failure in operation; treat as result being point at infinity */
531
LIB_EXPORT BOOL
532
BnEccModMult2(
533
        bigPoint             R,         // OUT: computed point
534
        pointConst           S,         // IN: optional point
535
        bigConst             d,         // IN: scalar for [d]S or [d]G
536
        pointConst           Q,         // IN: second point
537
        bigConst             u,         // IN: second scalar
538
        bigCurve             E          // IN: curve
539
        )
540
0
{
541
0
    EC_POINT            *pR = EC_POINT_new(E->G);
542
0
    EC_POINT            *pS = EcPointInitialized(S, E);
543
0
    BIG_INITIALIZED(bnD, d);
544
0
    EC_POINT            *pQ = EcPointInitialized(Q, E);
545
0
    BIG_INITIALIZED(bnU, u);
546
0
    if(S == NULL || S == (pointConst)&(AccessCurveData(E)->base))
547
0
  EC_POINT_mul(E->G, pR, bnD, pQ, bnU, E->CTX);
548
0
    else
549
0
  {
550
0
      const EC_POINT        *points[2];
551
0
      const BIGNUM          *scalars[2];
552
0
      points[0] = pS;
553
0
      points[1] = pQ;
554
0
      scalars[0] = bnD;
555
0
      scalars[1] = bnU;
556
0
      EC_POINTs_mul(E->G, pR, NULL, 2, points, scalars, E->CTX);
557
0
  }
558
0
    PointFromOssl(R, pR, E);
559
0
    EC_POINT_free(pR);
560
0
    EC_POINT_free(pS);
561
0
    EC_POINT_free(pQ);
562
0
    BN_free(bnD);
563
0
    BN_free(bnU);
564
0
    return !BnEqualZero(R->z);
565
0
}
566
/* B.2.3.2.4. BnEccAdd() */
567
/* This function does addition of two points. */
568
/* Return Values Meaning */
569
/* FALSE failure in operation; treat as result being point at infinity */
570
LIB_EXPORT BOOL
571
BnEccAdd(
572
   bigPoint             R,         // OUT: computed point
573
   pointConst           S,         // IN: point to multiply by 'd'
574
   pointConst           Q,         // IN: second point
575
   bigCurve             E          // IN: curve
576
   )
577
0
{
578
0
    EC_POINT            *pR = EC_POINT_new(E->G);
579
0
    EC_POINT            *pS = EcPointInitialized(S, E);
580
0
    EC_POINT            *pQ = EcPointInitialized(Q, E);
581
    //
582
0
    EC_POINT_add(E->G, pR, pS, pQ, E->CTX);
583
0
    PointFromOssl(R, pR, E);
584
0
    EC_POINT_free(pR);
585
0
    EC_POINT_free(pS);
586
0
    EC_POINT_free(pQ);
587
0
    return !BnEqualZero(R->z);
588
0
}
589
#endif // TPM_ALG_ECC
590
#endif // MATHLIB OSSL