aboutsummaryrefslogtreecommitdiff
path: root/RSAKeySieve.c
blob: b7614f502e7acab69ab038d9a9a2c242c9dccc24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include       "OsslCryptoEngine.h"
#ifdef       TPM_ALG_RSA
//
//     This file produces no code unless the compile switch is set to cause it to generate code.
//
#ifdef          RSA_KEY_SIEVE                          //%
#include        "RsaKeySieve.h"
//
//     This next line will show up in the header file for this code. It will make the local functions public when
//     debugging.
//
//%#ifdef       RSA_DEBUG
//
//
//      Bit Manipulation Functions
//
//          Introduction
//
//     These functions operate on a bit array. A bit array is an array of bytes with the 0th byte being the byte
//     with the lowest memory address. Within the byte, bit 0 is the least significant bit.
//
//          ClearBit()
//
//     This function will CLEAR a bit in a bit array.
//
void
ClearBit(
    unsigned char         *a,                     // IN: A pointer to an array of byte
    int                    i                      // IN: the number of the bit to CLEAR
    )
{
    a[i >> 3] &= 0xff ^ (1 << (i & 7));
}
//
//
//          SetBit()
//
//     Function to SET a bit in a bit array.
//
void
SetBit(
    unsigned char         *a,                     // IN: A pointer to an array of byte
    int                    i                      // IN: the number of the bit to SET
    )
{
    a[i >> 3] |= (1 << (i & 7));
}
//
//
//          IsBitSet()
//
//     Function to test if a bit in a bit array is SET.
//
//
//
//
//     Return Value                      Meaning
//
//     0                                 bit is CLEAR
//     1                                 bit is SET
//
UINT32
IsBitSet(
    unsigned char       *a,                   // IN: A pointer to an array of byte
    int                  i                    // IN: the number of the bit to test
    )
{
    return ((a[i >> 3] & (1 << (i & 7))) != 0);
}
//
//
//        BitsInArry()
//
//     This function counts the number of bits set in an array of bytes.
//
int
BitsInArray(
    unsigned char       *a,                   // IN: A pointer to an array of byte
    int                  i                    // IN: the number of bytes to sum
    )
{
    int     j = 0;
    for(; i ; i--)
        j += bitsInByte[*a++];
    return j;
}
//
//
//        FindNthSetBit()
//
//     This function finds the nth SET bit in a bit array. The caller should check that the offset of the returned
//     value is not out of range. If called when the array does not have n bits set, it will return a fatal error
//
UINT32
FindNthSetBit(
    const UINT16         aSize,               // IN: the size of the array to check
    const BYTE          *a,                   // IN: the array to check
    const UINT32         n                    // IN, the number of the SET bit
    )
{
    UINT32          i;
    const BYTE     *pA = a;
    UINT32          retValue;
    BYTE            sel;
    (aSize);
    //find the bit
    for(i = 0; i < n; i += bitsInByte[*pA++]);
    // The chosen bit is in the byte that was just accessed
    // Compute the offset to the start of that byte
    pA--;
    retValue = (UINT32)(pA - a) * 8;
    // Subtract the bits in the last byte added.
    i -= bitsInByte[*pA];
    // Now process the byte, one bit at a time.
    for(sel = *pA; sel != 0 ; sel = sel >> 1)
    {
        if(sel & 1)
        {
            i += 1;
            if(i == n)
                return retValue;
        }
        retValue += 1;
    }
    FAIL(FATAL_ERROR_INTERNAL);
}
//
//
//       Miscellaneous Functions
//
//          RandomForRsa()
//
//      This function uses a special form of KDFa() to produces a pseudo random sequence. It's input is a
//      structure that contains pointers to a pre-computed set of hash contexts that are set up for the HMAC
//      computations using the seed.
//      This function will test that ktx.outer will not wrap to zero if incremented. If so, the function returns FALSE.
//      Otherwise, the ktx.outer is incremented before each number is generated.
//
void
RandomForRsa(
    KDFa_CONTEXT        *ktx,                // IN: a context for the KDF
    const char          *label,              // IN: a use qualifying label
    TPM2B               *p                   // OUT: the pseudo random result
    )
{
    INT16                           i;
    UINT32                          inner;
    BYTE                            swapped[4];
    UINT16                          fill;
    BYTE                            *pb;
    UINT16                          lLen = 0;
    UINT16                          digestSize = _cpri__GetDigestSize(ktx->hashAlg);
    CPRI_HASH_STATE                 h;      // the working hash context
    if(label != NULL)
        for(lLen = 0; label[lLen++];);
    fill = digestSize;
    pb = p->buffer;
    inner = 0;
    *(ktx->outer) += 1;
    for(i = p->size; i > 0; i -= digestSize)
    {
        inner++;
         // Initialize the HMAC with saved state
         _cpri__CopyHashState(&h, &(ktx->iPadCtx));
         // Hash the inner counter (the one that changes on each HMAC iteration)
         UINT32_TO_BYTE_ARRAY(inner, swapped);
         _cpri__UpdateHash(&h, 4, swapped);
         if(lLen != 0)
             _cpri__UpdateHash(&h, lLen, (BYTE *)label);
         // Is there any party 1 data
         if(ktx->extra != NULL)
             _cpri__UpdateHash(&h, ktx->extra->size, ktx->extra->buffer);
        // Include the outer counter (the one that changes on each prime
        // prime candidate generation
        UINT32_TO_BYTE_ARRAY(*(ktx->outer), swapped);
        _cpri__UpdateHash(&h, 4, swapped);
        _cpri__UpdateHash(&h, 2, (BYTE *)&ktx->keySizeInBits);
        if(i < fill)
            fill = i;
        _cpri__CompleteHash(&h, fill, pb);
        // Restart the oPad hash
        _cpri__CopyHashState(&h, &(ktx->oPadCtx));
        // Add the last hashed data
        _cpri__UpdateHash(&h, fill, pb);
        // gives a completed HMAC
        _cpri__CompleteHash(&h, fill, pb);
        pb += fill;
   }
   return;
}
//
//
//         MillerRabinRounds()
//
//      Function returns the number of Miller-Rabin rounds necessary to give an error probability equal to the
//      security strength of the prime. These values are from FIPS 186-3.
//
UINT32
MillerRabinRounds(
   UINT32               bits                 // IN: Number of bits in the RSA prime
   )
{
   if(bits < 511) return 8;            // don't really expect this
   if(bits < 1536) return 5;           // for 512 and 1K primes
   return 4;                           // for 3K public modulus and greater
}
//
//
//         MillerRabin()
//
//      This function performs a Miller-Rabin test from FIPS 186-3. It does iterations trials on the number. I all
//      likelihood, if the number is not prime, the first test fails.
//      If a KDFa(), PRNG context is provide (ktx), then it is used to provide the random values. Otherwise, the
//      random numbers are retrieved from the random number generator.
//
//      Return Value                      Meaning
//
//      TRUE                              probably prime
//      FALSE                             composite
//
BOOL
MillerRabin(
   BIGNUM              *bnW,
   int                  iterations,
   KDFa_CONTEXT        *ktx,
   BN_CTX              *context
   )
{
   BIGNUM         *bnWm1;
   BIGNUM         *bnM;
   BIGNUM         *bnB;
   BIGNUM         *bnZ;
   BOOL         ret = FALSE;   // Assumed composite for easy exit
   TPM2B_TYPE(MAX_PRIME, MAX_RSA_KEY_BYTES/2);
   TPM2B_MAX_PRIME    b;
   int          a;
   int          j;
   int          wLen;
   int          i;
   pAssert(BN_is_bit_set(bnW, 0));
   INSTRUMENT_INC(MillerRabinTrials);    // Instrumentation
   BN_CTX_start(context);
   bnWm1 = BN_CTX_get(context);
   bnB = BN_CTX_get(context);
   bnZ = BN_CTX_get(context);
   bnM = BN_CTX_get(context);
   if(bnM == NULL)
       FAIL(FATAL_ERROR_ALLOCATION);
// Let a be the largest integer such that 2^a divides w1.
   BN_copy(bnWm1, bnW);
   BN_sub_word(bnWm1, 1);
   // Since w is odd (w-1) is even so start at bit number 1 rather than 0
   for(a = 1; !BN_is_bit_set(bnWm1, a); a++);
// 2. m = (w1) / 2^a
   BN_rshift(bnM, bnWm1, a);
// 3. wlen = len (w).
   wLen = BN_num_bits(bnW);
   pAssert((wLen & 7) == 0);
   // Set the size for the random number
   b.b.size = (UINT16)(wLen + 7)/8;
// 4. For i = 1 to iterations do
   for(i = 0; i < iterations ; i++)
   {
//  Obtain a string b of wlen bits from an RBG.
step4point1:
       // In the reference implementation, wLen is always a multiple of 8
       if(ktx != NULL)
            RandomForRsa(ktx, "Miller-Rabin witness", &b.b);
       else
            _cpri__GenerateRandom(b.t.size, b.t.buffer);
        if(BN_bin2bn(b.t.buffer, b.t.size, bnB) == NULL)
            FAIL(FATAL_ERROR_ALLOCATION);
//  If ((b 1) or (b w1)), then go to step 4.1.
       if(BN_is_zero(bnB))
           goto step4point1;
       if(BN_is_one(bnB))
           goto step4point1;
       if(BN_ucmp(bnB, bnWm1) >= 0)
           goto step4point1;
//  z = b^m mod w.
       if(BN_mod_exp(bnZ, bnB, bnM, bnW, context) != 1)
           FAIL(FATAL_ERROR_ALLOCATION);
//  If ((z = 1) or (z = w 1)), then go to step 4.7.
       if(BN_is_one(bnZ) || BN_ucmp(bnZ, bnWm1) == 0)
           goto step4point7;
//  For j = 1 to a 1 do.
       for(j = 1; j < a; j++)
       {
//  z = z^2 mod w.
           if(BN_mod_mul(bnZ, bnZ, bnZ, bnW, context) != 1)
               FAIL(FATAL_ERROR_ALLOCATION);
//  If (z = w1), then go to step 4.7.
           if(BN_ucmp(bnZ, bnWm1) == 0)
               goto step4point7;
//  If (z = 1), then go to step 4.6.
            if(BN_is_one(bnZ))
                goto step4point6;
       }
//  Return COMPOSITE.
step4point6:
       if(i > 9)
            INSTRUMENT_INC(failedAtIteration[9]);
       else
            INSTRUMENT_INC(failedAtIteration[i]);
       goto end;
//  Continue. Comment: Increment i for the do-loop in step 4.
step4point7:
       continue;
   }
// 5. Return PROBABLY PRIME
   ret = TRUE;
end:
   BN_CTX_end(context);
   return ret;
}
//
//
//         NextPrime()
//
//      This function is used to access the next prime number in the sequence of primes. It requires a pre-
//      initialized iterator.
//
UINT32
NextPrime(
   PRIME_ITERATOR      *iter
   )
{
   if(iter->index >= iter->final)
       return (iter->lastPrime = 0);
   return (iter->lastPrime += primeDiffTable[iter->index++]);
}
//
//
//         AdjustNumberOfPrimes()
//
//      Modifies the input parameter to be a valid value for the number of primes. The adjusted value is either the
//      input value rounded up to the next 512 bytes boundary or the maximum value of the implementation. If
//      the input is 0, the return is set to the maximum.
//
UINT32
AdjustNumberOfPrimes(
   UINT32               p
   )
{
   p = ((p + 511) / 512) * 512;
//
      if(p == 0 || p > PRIME_DIFF_TABLE_BYTES)
          p = PRIME_DIFF_TABLE_BYTES;
      return p;
}
//
//
//          PrimeInit()
//
//      This function is used to initialize the prime sequence generator iterator. The iterator is initialized and
//      returns the first prime that is equal to the requested starting value. If the starting value is no a prime, then
//      the iterator is initialized to the next higher prime number.
//
UINT32
PrimeInit(
      UINT32             first,              // IN: the initial prime
      PRIME_ITERATOR    *iter,               // IN/OUT: the iterator structure
      UINT32             primes              // IN: the table length
      )
{
      iter->lastPrime = 1;
      iter->index = 0;
      iter->final = AdjustNumberOfPrimes(primes);
      while(iter->lastPrime < first)
          NextPrime(iter);
      return iter->lastPrime;
}
//
//
//          SetDefaultNumberOfPrimes()
//
//      This macro sets the default number of primes to the indicated value.
//
//%#define SetDefaultNumberOfPrimes(p) (primeTableBytes = AdjustNumberOfPrimes(p))
//
//
//          IsPrimeWord()
//
//      Checks to see if a UINT32 is prime
//
//      Return Value                      Meaning
//
//      TRUE                              number is prime
//      FAIL                              number is not prime
//
BOOL
IsPrimeWord(
      UINT32              p                  // IN: number to test
      )
{
#if defined RSA_KEY_SIEVE && (PRIME_DIFF_TABLE_BYTES >= 6542)
      UINT32       test;
      UINT32       index;
      UINT32       stop;
      if((p & 1) == 0)
          return FALSE;
      if(p == 1 || p == 3)
          return TRUE;
      // Get a high value for the stopping point
      for(index = p, stop = 0; index; index >>= 2)
        stop = (stop << 1) + 1;
    stop++;
    // If the full prime difference value table is present, can check here
    test = 3;
    for(index = 1; index < PRIME_DIFF_TABLE_BYTES; index += 1)
    {
        if((p % test) == 0)
            return (p == test);
        if(test > stop)
            return TRUE;
        test += primeDiffTable[index];
    }
    return TRUE;
#else
   BYTE        b[4];
   if(p == RSA_DEFAULT_PUBLIC_EXPONENT || p == 1 || p == 3 )
       return TRUE;
   if((p & 1) == 0)
       return FALSE;
   UINT32_TO_BYTE_ARRAY(p,b);
   return _math__IsPrime(p);
#endif
}
typedef struct {
   UINT16      prime;
   UINT16      count;
} SIEVE_MARKS;
const SIEVE_MARKS sieveMarks[5] = {
   {31, 7}, {73, 5}, {241, 4}, {1621, 3}, {UINT16_MAX, 2}};
//
//
//          PrimeSieve()
//
//      This function does a prime sieve over the input field which has as its starting address the value in bnN.
//      Since this initializes the Sieve using a pre-computed field with the bits associated with 3, 5 and 7 already
//      turned off, the value of pnN may need to be adjusted by a few counts to allow the pre-computed field to
//      be used without modification. The fieldSize parameter must be 2^N + 1 and is probably not useful if it is
//      less than 129 bytes (1024 bits).
//
UINT32
PrimeSieve(
    BIGNUM        *bnN,            //   IN/OUT: number to sieve
    UINT32         fieldSize,      //   IN: size of the field area in bytes
    BYTE          *field,          //   IN: field
    UINT32         primes          //   IN: the number of primes to use
    )
{
    UINT32              i;
    UINT32              j;
    UINT32              fieldBits = fieldSize * 8;
    UINT32              r;
    const BYTE         *p1;
    BYTE               *p2;
    PRIME_ITERATOR      iter;
    UINT32              adjust;
    UINT32              mark = 0;
    UINT32              count = sieveMarks[0].count;
    UINT32              stop = sieveMarks[0].prime;
    UINT32              composite;
//      UINT64              test;           //DEBUG
   pAssert(field != NULL && bnN != NULL);
   // Need to have a field that has a size of 2^n + 1 bytes
   pAssert(BitsInArray((BYTE *)&fieldSize, 2) == 2);
   primes = AdjustNumberOfPrimes(primes);
   // If the remainder is odd, then subtracting the value
   // will give an even number, but we want an odd number,
   // so subtract the 105+rem. Otherwise, just subtract
   // the even remainder.
   adjust = BN_mod_word(bnN,105);
   if(adjust & 1)
       adjust += 105;
   // seed the field
   // This starts the pointer at the nearest byte to the input value
   p1 = &seedValues[adjust/16];
   // Reduce the number of bytes to transfer by the amount skipped
   j = sizeof(seedValues) - adjust/16;
   adjust = adjust % 16;
   BN_sub_word(bnN, adjust);
   adjust >>= 1;
   // This offsets the field
   p2 = field;
   for(i = fieldSize; i > 0; i--)
   {
       *p2++ = *p1++;
       if(--j == 0)
       {
           j = sizeof(seedValues);
           p1 = seedValues;
       }
   }
   // Mask the first bits in the field and the last byte in order to eliminate
   // bytes not in the field from consideration.
   field[0] &= 0xff << adjust;
   field[fieldSize-1] &= 0xff >> (8 - adjust);
   // Cycle through the primes, clearing bits
   // Have already done 3, 5, and 7
   PrimeInit(7, &iter, primes);
   // Get the next N primes where N is determined by the mark in the sieveMarks
   while((composite = NextPrime(&iter)) != 0)
   {
       UINT32 pList[8];
       UINT32   next = 0;
       i = count;
       pList[i--] = composite;
       for(; i > 0; i--)
       {
           next = NextPrime(&iter);
           pList[i] = next;
           if(next != 0)
               composite *= next;
       }
       composite = BN_mod_word(bnN, composite);
       for(i = count; i > 0; i--)
       {
           next = pList[i];
           if(next == 0)
               goto done;
           r = composite % next;
              if(r & 1)           j = (next - r)/2;
              else if(r == 0)     j = 0;
              else                j = next - r/2;
              for(; j < fieldBits; j += next)
                  ClearBit(field, j);
         }
         if(next >= stop)
         {
             mark++;
             count = sieveMarks[mark].count;
             stop = sieveMarks[mark].prime;
         }
   }
done:
   INSTRUMENT_INC(totalFieldsSieved);
   i = BitsInArray(field, fieldSize);
   if(i == 0) INSTRUMENT_INC(emptyFieldsSieved);
   return i;
}
//
//
//       PrimeSelectWithSieve()
//
//      This function will sieve the field around the input prime candidate. If the sieve field is not empty, one of
//      the one bits in the field is chosen for testing with Miller-Rabin. If the value is prime, pnP is updated with
//      this value and the function returns success. If this value is not prime, another pseudo-random candidate
//      is chosen and tested. This process repeats until all values in the field have been checked. If all bits in the
//      field have been checked and none is prime, the function returns FALSE and a new random value needs
//      to be chosen.
//
BOOL
PrimeSelectWithSieve(
   BIGNUM               *bnP,                    // IN/OUT: The candidate to filter
   KDFa_CONTEXT         *ktx,                    // IN: KDFa iterator structure
   UINT32                e,                      // IN: the exponent
   BN_CTX               *context                 // IN: the big number context to play in
#ifdef RSA_DEBUG                                  //%
  ,UINT16                fieldSize,              // IN: number of bytes in the field, as
                                                 //     determined by the caller
   UINT16            primes                      // IN: number of primes to use.
#endif                                            //%
)
{
   BYTE              field[MAX_FIELD_SIZE];
   UINT32            first;
   UINT32            ones;
   INT32             chosen;
   UINT32            rounds = MillerRabinRounds(BN_num_bits(bnP));
#ifndef RSA_DEBUG
   UINT32            primes;
   UINT32            fieldSize;
   // Adjust the field size and prime table list to fit the size of the prime
   // being tested.
   primes = BN_num_bits(bnP);
   if(primes <= 512)
   {
       primes = AdjustNumberOfPrimes(2048);
       fieldSize = 65;
   }
   else if(primes <= 1024)
   {
       primes = AdjustNumberOfPrimes(4096);
       fieldSize = 129;
   }
//
   else
   {
       primes = AdjustNumberOfPrimes(0);             // Set to the maximum
       fieldSize = MAX_FIELD_SIZE;
   }
   if(fieldSize > MAX_FIELD_SIZE)
       fieldSize = MAX_FIELD_SIZE;
#endif
    // Save the low-order word to use as a search generator and make sure that
    // it has some interesting range to it
    first = bnP->d[0] | 0x80000000;
   // Align to field boundary
   bnP->d[0] &= ~((UINT32)(fieldSize-3));
   pAssert(BN_is_bit_set(bnP, 0));
   bnP->d[0] &= (UINT32_MAX << (FIELD_POWER + 1)) + 1;
   ones = PrimeSieve(bnP, fieldSize, field, primes);
#ifdef RSA_FILTER_DEBUG
   pAssert(ones == BitsInArray(field, defaultFieldSize));
#endif
   for(; ones > 0; ones--)
   {
#ifdef RSA_FILTER_DEBUG
       if(ones != BitsInArray(field, defaultFieldSize))
           FAIL(FATAL_ERROR_INTERNAL);
#endif
       // Decide which bit to look at and find its offset
       if(ones == 1)
           ones = ones;
       chosen = FindNthSetBit(defaultFieldSize, field,((first % ones) + 1));
       if(chosen >= ((defaultFieldSize) * 8))
           FAIL(FATAL_ERROR_INTERNAL);
         // Set this as the trial prime
         BN_add_word(bnP, chosen * 2);
         // Use MR to see if this is prime
         if(MillerRabin(bnP, rounds, ktx, context))
         {
             // Final check is to make sure that 0 != (p-1) mod e
             // This is the same as -1 != p mod e ; or
             // (e - 1) != p mod e
             if((e <= 3) || (BN_mod_word(bnP, e) != (e-1)))
                 return TRUE;
         }
         // Back out the bit number
         BN_sub_word(bnP, chosen * 2);
         // Clear the bit just tested
         ClearBit(field, chosen);
}
    // Ran out of bits and couldn't find a prime in this field
    INSTRUMENT_INC(noPrimeFields);
    return FALSE;
}
//
//
//       AdjustPrimeCandiate()
//
//      This function adjusts the candidate prime so that it is odd and > root(2)/2. This allows the product of these
//      two numbers to be .5, which, in fixed point notation means that the most significant bit is 1. For this
//      routine, the root(2)/2 is approximated with 0xB505 which is, in fixed point is 0.7071075439453125 or an
//      error of 0.0001%. Just setting the upper two bits would give a value > 0.75 which is an error of > 6%.
//
//
//      Given the amount of time all the other computations take, reducing the error is not much of a cost, but it
//      isn't totally required either.
//      The function also puts the number on a field boundary.
//
void
AdjustPrimeCandidate(
   BYTE                *a,
   UINT16               len
   )
{
   UINT16    highBytes;
   highBytes = BYTE_ARRAY_TO_UINT16(a);
   // This is fixed point arithmetic on 16-bit values
   highBytes = ((UINT32)highBytes * (UINT32)0x4AFB) >> 16;
   highBytes += 0xB505;
   UINT16_TO_BYTE_ARRAY(highBytes, a);
   a[len-1] |= 1;
}
//
//
//       GeneratateRamdomPrime()
//
void
GenerateRandomPrime(
   TPM2B  *p,
   BN_CTX *ctx
#ifdef RSA_DEBUG               //%
  ,UINT16  field,
   UINT16  primes
#endif                         //%
   )
{
   BIGNUM *bnP;
   BN_CTX *context;
   if(ctx == NULL) context = BN_CTX_new();
   else context = ctx;
   if(context == NULL)
       FAIL(FATAL_ERROR_ALLOCATION);
   BN_CTX_start(context);
   bnP = BN_CTX_get(context);
   while(TRUE)
   {
       _cpri__GenerateRandom(p->size, p->buffer);
       p->buffer[p->size-1] |= 1;
       p->buffer[0] |= 0x80;
       BN_bin2bn(p->buffer, p->size, bnP);
#ifdef RSA_DEBUG
       if(PrimeSelectWithSieve(bnP, NULL, 0, context, field, primes))
#else
       if(PrimeSelectWithSieve(bnP, NULL, 0, context))
#endif
           break;
   }
   BnTo2B(p, bnP, (UINT16)BN_num_bytes(bnP));
   BN_CTX_end(context);
   if(ctx == NULL)
       BN_CTX_free(context);
   return;
}
KDFa_CONTEXT *
KDFaContextStart(
    KDFa_CONTEXT        *ktx,                //   IN/OUT:   the context structure to initialize
    TPM2B               *seed,               //   IN: the   seed for the digest proce
    TPM_ALG_ID           hashAlg,            //   IN: the   hash algorithm
    TPM2B               *extra,              //   IN: the   extra data
    UINT32              *outer,              //   IN: the   outer iteration counter
    UINT16               keySizeInBit
    )
{
    UINT16                     digestSize = _cpri__GetDigestSize(hashAlg);
    TPM2B_HASH_BLOCK           oPadKey;
    if(seed == NULL)
        return NULL;
    pAssert(ktx != NULL && outer != NULL && digestSize != 0);
   // Start the hash using the seed and get the intermediate hash value
   _cpri__StartHMAC(hashAlg, FALSE, &(ktx->iPadCtx), seed->size, seed->buffer,
                    &oPadKey.b);
   _cpri__StartHash(hashAlg, FALSE, &(ktx->oPadCtx));
   _cpri__UpdateHash(&(ktx->oPadCtx), oPadKey.b.size, oPadKey.b.buffer);
   ktx->extra = extra;
   ktx->hashAlg = hashAlg;
   ktx->outer = outer;
   ktx->keySizeInBits = keySizeInBits;
   return ktx;
}
void
KDFaContextEnd(
    KDFa_CONTEXT        *ktx                 // IN/OUT: the context structure to close
    )
{
    if(ktx != NULL)
    {
        // Close out the hash sessions
        _cpri__CompleteHash(&(ktx->iPadCtx), 0, NULL);
        _cpri__CompleteHash(&(ktx->oPadCtx), 0, NULL);
    }
}
//%#endif
//
//
//       Public Function
//
//         Introduction
//
//      This is the external entry for this replacement function. All this file provides is the substitute function to
//      generate an RSA key. If the compiler settings are set appropriately, this this function will be used instead
//      of the similarly named function in CpriRSA.c.
//
//         _cpri__GenerateKeyRSA()
//
//      Generate an RSA key from a provided seed
//
//      Return Value                     Meaning
//
//      CRYPT_FAIL                       exponent is not prime or is less than 3; or could not find a prime using
//                                       the provided parameters
//      CRYPT_CANCEL                     operation was canceled
//
LIB_EXPORT CRYPT_RESULT
_cpri__GenerateKeyRSA(
   TPM2B              *n,               // OUT: The public modulus
   TPM2B              *p,               // OUT: One of the prime factors of n
   UINT16              keySizeInBits,   // IN: Size of the public modulus in bits
   UINT32              e,               // IN: The public exponent
   TPM_ALG_ID          hashAlg,         // IN: hash algorithm to use in the key
                                        //     generation process
   TPM2B              *seed,            // IN: the seed to use
   const char         *label,           // IN: A label for the generation process.
   TPM2B              *extra,           // IN: Party 1 data for the KDF
   UINT32             *counter          // IN/OUT: Counter value to allow KDF
                                        //         iteration to be propagated across
                                        //         multiple routines
#ifdef RSA_DEBUG                         //%
  ,UINT16              primes,          // IN: number of primes to test
   UINT16              fieldSize        // IN: the field size to use
#endif                                   //%
   )
{
   CRYPT_RESULT             retVal;
   UINT32                   myCounter = 0;
   UINT32                  *pCtr = (counter == NULL) ? &myCounter : counter;
   KDFa_CONTEXT             ktx;
   KDFa_CONTEXT            *ktxPtr;
   UINT32                   i;
   BIGNUM                  *bnP;
   BIGNUM                  *bnQ;
   BIGNUM                  *bnT;
   BIGNUM                  *bnE;
   BIGNUM                  *bnN;
   BN_CTX                  *context;
   // Make sure that the required pointers are provided
   pAssert(n != NULL && p != NULL);
   // If the seed is provided, then use KDFa for generation of the 'random'
   // values
   ktxPtr = KDFaContextStart(&ktx, seed, hashAlg, extra, pCtr, keySizeInBits);
   n->size = keySizeInBits/8;
   p->size = n->size / 2;
   // Validate exponent
   if(e == 0 || e == RSA_DEFAULT_PUBLIC_EXPONENT)
       e = RSA_DEFAULT_PUBLIC_EXPONENT;
   else
       if(!IsPrimeWord(e))
           return CRYPT_FAIL;
   // Get structures for the big number representations
   context = BN_CTX_new();
   BN_CTX_start(context);
   bnP = BN_CTX_get(context);
   bnQ = BN_CTX_get(context);
   bnT = BN_CTX_get(context);
   bnE = BN_CTX_get(context);
   bnN = BN_CTX_get(context);
   if(bnN == NULL)
       FAIL(FATAL_ERROR_INTERNAL);
   //   Set Q to zero. This is used as a flag. The prime is computed in P. When a
   //   new prime is found, Q is checked to see if it is zero. If so, P is copied
   //   to Q and a new P is found. When both P and Q are non-zero, the modulus and
   //   private exponent are computed and a trial encryption/decryption is
   //   performed. If the encrypt/decrypt fails, assume that at least one of the
   //   primes is composite. Since we don't know which one, set Q to zero and start
   // over and find a new pair of primes.
   BN_zero(bnQ);
   BN_set_word(bnE, e);
   // Each call to generate a random value will increment ktx.outer
   // it doesn't matter if ktx.outer wraps. This lets the caller
   // use the initial value of the counter for additional entropy.
   for(i = 0; i < UINT32_MAX; i++)
   {
       if(_plat__IsCanceled())
       {
            retVal = CRYPT_CANCEL;
            goto end;
       }
       // Get a random prime candidate.
       if(seed == NULL)
            _cpri__GenerateRandom(p->size, p->buffer);
       else
            RandomForRsa(&ktx, label, p);
       AdjustPrimeCandidate(p->buffer, p->size);
         // Convert the candidate to a BN
         if(BN_bin2bn(p->buffer, p->size, bnP) == NULL)
             FAIL(FATAL_ERROR_INTERNAL);
         // If this is the second prime, make sure that it differs from the
         // first prime by at least 2^100. Since BIGNUMS use words, the check
         // below will make sure they are different by at least 128 bits
         if(!BN_is_zero(bnQ))
         { // bnQ is non-zero, we have a first value
             UINT32       *pP = (UINT32 *)(&bnP->d[4]);
             UINT32       *pQ = (UINT32 *)(&bnQ->d[4]);
             INT32        k = ((INT32)bnP->top) - 4;
             for(;k > 0; k--)
                 if(*pP++ != *pQ++)
                     break;
             // Didn't find any difference so go get a new value
             if(k == 0)
                 continue;
         }
         // If PrimeSelectWithSieve   returns success, bnP is a prime,
#ifdef    RSA_DEBUG
         if(!PrimeSelectWithSieve(bnP, ktxPtr, e, context, fieldSize, primes))
#else
         if(!PrimeSelectWithSieve(bnP, ktxPtr, e, context))
#endif
              continue;      // If not, get another
         // Found a prime, is this the first or second.
         if(BN_is_zero(bnQ))
         {    // copy p to q and compute another prime in p
              BN_copy(bnQ, bnP);
              continue;
         }
         //Form the public modulus
        if(    BN_mul(bnN, bnP, bnQ, context) != 1
            || BN_num_bits(bnN) != keySizeInBits)
              FAIL(FATAL_ERROR_INTERNAL);
        // Save the public modulus
        BnTo2B(n, bnN, n->size);
        // And one prime
        BnTo2B(p, bnP, p->size);
#ifdef EXTENDED_CHECKS
       // Finish by making sure that we can form the modular inverse of PHI
       // with respect to the public exponent
       // Compute PHI = (p - 1)(q - 1) = n - p - q + 1
        // Make sure that we can form the modular inverse
        if(    BN_sub(bnT, bnN, bnP) != 1
            || BN_sub(bnT, bnT, bnQ) != 1
            || BN_add_word(bnT, 1) != 1)
             FAIL(FATAL_ERROR_INTERNAL);
        // find d such that (Phi * d) mod e ==1
        // If there isn't then we are broken because we took the step
        // of making sure that the prime != 1 mod e so the modular inverse
        // must exist
        if(    BN_mod_inverse(bnT, bnE, bnT, context) == NULL
            || BN_is_zero(bnT))
             FAIL(FATAL_ERROR_INTERNAL);
        // And, finally, do a trial encryption decryption
        {
            TPM2B_TYPE(RSA_KEY, MAX_RSA_KEY_BYTES);
            TPM2B_RSA_KEY        r;
            r.t.size = sizeof(r.t.buffer);
            // If we are using a seed, then results must be reproducible on each
            // call. Otherwise, just get a random number
            if(seed == NULL)
                _cpri__GenerateRandom(keySizeInBits/8, r.t.buffer);
            else
                RandomForRsa(&ktx, label, &r.b);
             // Make sure that the number is smaller than the public modulus
             r.t.buffer[0] &= 0x7F;
                    // Convert
             if(    BN_bin2bn(r.t.buffer, r.t.size, bnP) == NULL
                    // Encrypt with the public exponent
                 || BN_mod_exp(bnQ, bnP, bnE, bnN, context) != 1
                    // Decrypt with the private exponent
                 || BN_mod_exp(bnQ, bnQ, bnT, bnN, context) != 1)
                  FAIL(FATAL_ERROR_INTERNAL);
             // If the starting and ending values are not the same, start over )-;
             if(BN_ucmp(bnP, bnQ) != 0)
             {
                  BN_zero(bnQ);
                  continue;
             }
       }
#endif // EXTENDED_CHECKS
       retVal = CRYPT_SUCCESS;
       goto end;
   }
   retVal = CRYPT_FAIL;
end:
   KDFaContextEnd(&ktx);
   // Free up allocated BN values
   BN_CTX_end(context);
   BN_CTX_free(context);
   return retVal;
}
#endif              //%
#endif // TPM_ALG_RSA