>
> dbrumley> BN_dec2bn() in bn_print.c. I'll call it my "problem" until
> dbrumley> confirmed.
> [...]
> dbrumley> The problem seems to be calling BN_dec2bn with an already
> dbrumley> allocated BIGNUM that's been previously used.  Inside
> dbrumley> BN_dec2bn the code is something like:
> dbrumley> int BN_dec2bn(BIGNUM **bn, const char *a){
> dbrumley>   BIGNUM *ret = NULL;
> dbrumley>   ...
> dbrumley>   if(*bn == NULL){
> dbrumley>    ret = BN_new();
> dbrumley>   } else {
> dbrumley>    ret = *bn;
> dbrumley>    BN_zero(ret);   // Call this line a
> dbrumley>   }
> dbrumley>   .. yadada ..
> dbrumley>   while(*a) {
> dbrumley>        ...
> dbrumley>        BN_mul_word(ret,BN_DEC_CONV);  //call this line b
> dbrumley>        BN_add_word(ret, l);
> dbrumley>        ....
> dbrumley>   }
> dbrumley>   *bn = ret;
> dbrumley>   ...
> dbrumley> }
> dbrumley>
> dbrumley> This function appears to want to decide whether or not the
> dbrumley> parameter bn has already been allocated.
>
> Correct.
>
> dbrumley> If not, allocated a fresh BIGNUM.  If so, zero out the
> dbrumley> bignum (e.g. line a).  However, BN_zero() doesn't actually
> dbrumley> zero out all of the BIGNUM structure, i.e.  d[1-top] isn't
> dbrumley> zeroed out, only d[0] in struct BIGNUM.
>
> Correct, but it does change top (sets it to 0) as well, so talking
> about the range d[1-top] is a moot point.
>
> dbrumley> The problem seems to be manifested in BN_dec2bn() because of
> dbrumley> the BN_mul_words and BN_add_words (e.g. line b).  Since the
> dbrumley> upper parts of d aren't cleared out, those routines end up
> dbrumley> adding to whatever junk happened to be left in d from the
> dbrumley> previous iteration.
>
> Perhaps there's a bug in those.
>
> Can you send us a small piece of code that actually shows the problem?
> Please send us the result that you get, so we can compare.

The following program with the attached input file gives the problem.  The 
output doesn't match the input when ran (which it should).  Note that the 
length of the second input is less than that of the first, leaving junk in 
struct bignum.  I've traced the problem in BN_dec2bn() and noticed that if 
u=NULL, the second round of the conversion leaves a different value in ret 
than if u != NULL (which is why I think the bug is in this function).

One thing that's important to note is that if you then take the numbers 
returned via BN_dec2bn() in the below code and execute RSA_eay_mod_exp as an 
RSA decryption, the CRT decryption will fail, i.e:
  i^d mod n = r0       (using CRT)
 r0^e mod n = vrfy  
 vrfy != r0
I suppose since the check is there it's okay, but it gives me the willies 
(i.e. w/o the check you've given me the factors to n) even so. Again, I think 
the key is (input1) > (input2), and BN_zero() doesn't clear out all of d, so 
so you could end up with a situation where residues spill over into the 
uncleared portions of the d array.

int main()
{
  RSA *key;
  FILE *in;
  BIGNUM *myu;
  char buf[512];
  BIGNUM *u, *res;
  int i, foo;

  res = BN_new();
  u = BN_new();

  in = fopen("input", "r");

  fgets(buf, sizeof(buf), in);
  if(buf[strlen(buf)-1] == '\n')
   buf[strlen(buf)-1] = '\0';
  BN_dec2bn(&u, buf);
  printf("%s\n", BN_bn2dec(u));

  fgets(buf, sizeof(buf), in);
  if(buf[strlen(buf)-1] == '\n')
    buf[strlen(buf)-1] = '\0';
  BN_dec2bn(&u, buf);
  printf("%s\n", BN_bn2dec(u));

  return 1;
}

104754998813132780202425634599286369024850780921440298951718133795637988956234464827230787966845282649587476155995396385373082708201846101878402988938054350969490656345106710961215694670270739615512806253518226267314630041847050614232641505668419388691871626540493259504026005747088762033683261864670835372155
4722458329183954277105491041962996603409754740561325475015546125828803424044991832369460094179140841497077646972492610505974663109452162870719116158955551140500351081865772089421292875859281646860632573488638061665085838699370304197757954908234333189524405289062611405243270983073690463321318122395101011548

Reply via email to