]> andersk Git - moira.git/blob - util/gdss/lib/crypto/algorithm/bigrsacode.c
initial import of gdss from the Athena source tree
[moira.git] / util / gdss / lib / crypto / algorithm / bigrsacode.c
1 /*
2  * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
3  * ALL RIGHTS RESERVED
4  *
5  * "Digital Equipment Corporation authorizes the reproduction,
6  * distribution and modification of this software subject to the following
7  * restrictions:
8  * 
9  * 1.  Any partial or whole copy of this software, or any modification
10  * thereof, must include this copyright notice in its entirety.
11  *
12  * 2.  This software is supplied "as is" with no warranty of any kind,
13  * expressed or implied, for any purpose, including any warranty of fitness 
14  * or merchantibility.  DIGITAL assumes no responsibility for the use or
15  * reliability of this software, nor promises to provide any form of 
16  * support for it on any basis.
17  *
18  * 3.  Distribution of this software is authorized only if no profit or
19  * remuneration of any kind is received in exchange for such distribution.
20  * 
21  * 4.  This software produces public key authentication certificates
22  * bearing an expiration date established by DIGITAL and RSA Data
23  * Security, Inc.  It may cease to generate certificates after the expiration
24  * date.  Any modification of this software that changes or defeats
25  * the expiration date or its effect is unauthorized.
26  * 
27  * 5.  Software that will renew or extend the expiration date of
28  * authentication certificates produced by this software may be obtained
29  * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
30  * 94065, (415)595-8782, or from DIGITAL"
31  *
32  */
33
34 #include <stdio.h>
35 #include <sys/types.h>
36 #include "BigNum.h"
37 #include "BigRSA.h"
38
39 #ifdef DEBUG
40 #undef DEBUG
41 #endif
42
43 /*
44  * These routines convert ASN.1 to RSAKeyStorage and vice-versa.
45  */
46
47 #define INTEGER_TAG     2
48 #define BITSTRING_TAG   3
49 #define SEQUENCE_TAG    48
50 #define CONTEXT_0_TAG   160
51 #define CONTEXT_1_TAG   161
52 #define CONTEXT_2_TAG   162
53 #define CONTEXT_3_TAG   163
54 #define CONTEXT_4_TAG   164
55 #define CONTEXT_5_TAG   165
56
57 /*
58  * Routines for encoding keys.
59  */
60  
61 /* 
62  * Compute total size of length field assuming minimal (X.509) encoding.
63  */
64
65 int NumEncodeLengthOctets (size) 
66 int size;
67 {
68         int i = 2;
69         if (size<128) i=1; else if (size>256) i=3 ;
70         return(i);
71 }
72
73 /*
74  *  Write out length, advance pointer to next thing to be written.
75  */
76 unsigned char *EncodeLength (input, size)
77 unsigned char *input;
78 int size;
79 {
80         int i = NumEncodeLengthOctets(size);
81
82         if (i==1) (*input++)=(unsigned char)size ;
83         else {  i--;
84                 (*input++)= i+0x80;
85                 for (i--;i>=0;i--) (*input++)=(size>>(i*8));
86         }
87         return(input);
88 }
89
90 /* 
91  * Compute the value of the INTEGER encoded length field for a BigNum 
92  * of length nl.
93  */
94 int NumEncodeValueOctets(n,nl)
95 int nl;
96 BigNum n;
97 {
98         int i,j;
99         
100         if (n==0) return (0);
101         
102         i = BnnNumDigits(n,nl);
103         j = BnnNumLeadingZeroBitsInDigit(BnnGetDigit(n+i-1));
104
105         i=i*sizeof(int)-j/8;
106         if ((j%8)==0)i++;
107         return(i);
108 }
109
110 /* 
111  * Write out BigNum as encoded INTEGER, most to least significant octet, and
112  * return pointer to next octet in stream.  Expects to be supplied with
113  * a sufficiently large buffer.  Always expects the BigNum to be positive.
114  */
115 unsigned char *EncodeBigIntegerValue (stream, input, size)
116 unsigned char *stream;
117 BigNum input;
118 unsigned size; 
119 {
120         int nl = BnnNumDigits(input, size);
121         BigNumDigit d = BnnGetDigit(input+nl-1);
122         int i = BnnNumLeadingZeroBitsInDigit(d);
123
124         if ((i%8)==0) *stream++ = 0;      /* want positive number, after all */
125         for(i=sizeof(int)-(i/8)-1;i>=0;i--) *stream++ = (unsigned char) (d>>(i*8))&0xff;
126         for(nl--;nl>0;nl--){
127                   d = BnnGetDigit(input+nl-1);
128                   for(i=sizeof(int)-1;i>=0;i--) *stream++ = (d>>(i*8))&0xff;
129         }
130         return(stream);
131 }
132
133 /*
134  * Make an encoded public key from RSAKeyStorage.  This includes allocating
135  * the stream storage.
136  *
137  * A public key is defined as SEQUENCE { INTEGER, INTEGER }
138  */
139 unsigned char *EncodePublic(keys)
140 RSAKeyStorage *keys;
141 {
142         int mod_len,exp_len,sequence_len,public_key_len ;
143         unsigned char *buffer, *start;
144
145         if ((keys->nl)==0) return(0);
146         
147         mod_len = NumEncodeValueOctets(keys->n,keys->nl);
148         exp_len = NumEncodeValueOctets(keys->e,keys->el);
149         sequence_len = exp_len + mod_len + NumEncodeLengthOctets(exp_len)+
150                 NumEncodeLengthOctets(mod_len)+2;
151         public_key_len = NumEncodeLengthOctets(sequence_len)+sequence_len+1;
152
153         if (start = buffer = (unsigned char *) calloc(public_key_len,1)) {
154                 *buffer++ = SEQUENCE_TAG;
155                 buffer = EncodeLength (buffer,sequence_len);
156                 *buffer++= INTEGER_TAG; 
157                 buffer=EncodeLength (buffer,mod_len);
158                 buffer=EncodeBigIntegerValue(buffer,keys->n,keys->nl);
159                 *buffer++= INTEGER_TAG; 
160                 buffer=EncodeLength (buffer,exp_len);
161                 buffer=EncodeBigIntegerValue (buffer,keys->e,keys->el);
162         }
163         return(start);
164 }
165
166 void FreePublic(buffer)
167 {       free(buffer);
168 }
169
170 /*
171  * Make an encoded private key from RSAKeyStorage.  This includes allocating
172  * the stream storage.
173  *
174  * A private key is defined as 
175  *   SEQUENCE { 
176  *              primep     INTEGER,           -- always there
177  *              primeq [0] INTEGER OPTIONAL,
178  *              mod    [1] INTEGER OPTIONAL,  -- never there
179  *              exp    [2] INTEGER OPTIONAL,
180  *              dp     [3] INTEGER OPTIONAL,
181  *              dq     [4] INTEGER OPTIONAL,
182  *              cr     [5] INTEGER OPTIONAL }
183  */ 
184 unsigned char *EncodePrivate(keys)
185 RSAKeyStorage *keys;
186 {
187         int p_len, q_len, exp_len, dp_len, dq_len, cr_len, sequence_len ;
188         unsigned char *buffer, *start;
189
190         /* must have two primes to be a private key */
191         if ((keys->pl ==0)||(keys->ql ==0)) return(0);
192
193         sequence_len = 6 +
194                 (p_len = NumEncodeValueOctets(keys->p,keys->pl)) +
195                 NumEncodeLengthOctets(p_len) +
196                 (q_len = NumEncodeValueOctets(keys->q,keys->ql)) +
197                 NumEncodeLengthOctets(q_len) +
198                 (exp_len = NumEncodeValueOctets(keys->e,keys->el)) +
199                 NumEncodeLengthOctets(exp_len) + 
200                 (dp_len = NumEncodeValueOctets(keys->dp,keys->dpl)) +
201                 NumEncodeLengthOctets(dp_len) +
202                 (dq_len = NumEncodeValueOctets(keys->dq,keys->dql)) +
203                 NumEncodeLengthOctets(dq_len) + 
204                 (cr_len = NumEncodeValueOctets(keys->cr,keys->pl)) +
205                 NumEncodeLengthOctets(cr_len);            
206
207         if (start=buffer= 
208          (unsigned char *)calloc(1+NumEncodeLengthOctets(sequence_len)+sequence_len,1)) {
209                 *buffer++ = SEQUENCE_TAG;
210                 buffer=EncodeLength (buffer,sequence_len);
211                 *buffer++= INTEGER_TAG; 
212                 buffer=EncodeLength (buffer,p_len);
213                 buffer=EncodeBigIntegerValue (buffer,keys->p,keys->pl);
214                 *buffer++= CONTEXT_0_TAG;       
215                 buffer=EncodeLength (buffer,q_len);
216                 buffer=EncodeBigIntegerValue (buffer,keys->q,keys->ql);
217                 /*
218                  * No optional modulus.
219                  */
220                 *buffer++= CONTEXT_2_TAG;
221                 buffer=EncodeLength (buffer,exp_len);
222                 buffer=EncodeBigIntegerValue (buffer,keys->e,keys->el);
223                 *buffer++= CONTEXT_3_TAG;
224                 buffer=EncodeLength (buffer,dp_len);
225                 buffer=EncodeBigIntegerValue (buffer,keys->dp,keys->dpl);
226                 *buffer++= CONTEXT_4_TAG;
227                 buffer=EncodeLength (buffer,dq_len);
228                 buffer=EncodeBigIntegerValue (buffer,keys->dq,keys->dql);
229                 *buffer++= CONTEXT_5_TAG;
230                 buffer=EncodeLength (buffer,cr_len);
231                 buffer=EncodeBigIntegerValue (buffer,keys->cr,keys->pl);
232         }
233         return(start);
234 }
235
236 /* 
237  * The following routine is similar to the above but just puts prime p in 
238  * the encoded private key.
239  */
240 unsigned char *EncodePrivateP(keys)
241 RSAKeyStorage *keys;
242 {
243         int p_len = NumEncodeValueOctets(keys->p,keys->pl);
244         int sequence_len = p_len + 1 + NumEncodeLengthOctets(p_len) ;
245         unsigned char *start, *buffer ;
246
247         if (start=buffer= (unsigned char *)
248              calloc(1+NumEncodeLengthOctets(sequence_len)+sequence_len, 1)) {
249                 *buffer++ = SEQUENCE_TAG;
250                 buffer=EncodeLength (buffer,sequence_len);
251                 *buffer++= INTEGER_TAG; 
252                 buffer=EncodeLength (buffer,p_len);
253                 buffer=EncodeBigIntegerValue (buffer,keys->p,keys->pl);
254         }
255         return(start);
256 }
257
258 void FreePrivate(buffer)
259 {       free(buffer);
260 }
261
262
263 /*
264  * Decoding routines.
265  */
266  
267 /*
268  * Input is an encoded value field, tells how many octets in the value.
269  * Does not handle indefinite length forms.
270  */
271 int DecodeValueLength (input) /* handles non-minimal size case */
272 unsigned char *input ;
273 {
274         int len , i ;
275
276         if ((*input&0x80)==0) return(*input);
277         if (*input==0x80) return(0);
278         for (i=(*input++ & 0x7f),len=0;i>0;i--) len=(len << 8)+(unsigned int)*input++;
279
280         return(len);
281 }
282
283 /*
284  * Input is undecoded string.  Returns offset to start of value field.
285  */
286 int DecodeHeaderLength (input)
287 unsigned char *input ;
288 {
289         int tlen = DecodeTypeLength(input);
290         input+=tlen;
291         tlen++;
292         if (*input&0x80) tlen += (*input&0x7f);
293         return(tlen);
294 }
295
296 /*
297  * Compute number of type bytes.
298  */
299 int DecodeTypeLength (input)
300 unsigned char *input;
301 {       int temp=1;
302         if ((*input&31)==31) do {input++;temp++;} while (*input&0x80) ;
303         return(temp);
304 }
305
306 /*
307  * Compute offset to next element to decode.
308  * Assumes definite length encoding.
309  */
310 int DecodeTotalLength (input)
311 unsigned char *input ;
312 {
313  return (DecodeHeaderLength(input)+DecodeValueLength(input+DecodeTypeLength(input)));
314 }
315
316 /* 
317  *  DecodeBigInteger Returns pointer to one byte beyond end of encoded value.
318  *  Reads in least to most significant.
319  */
320 unsigned char *DecodeBigInteger (stream, value, size)
321 unsigned char *stream;
322 BigNum value ;
323 int size;
324 {
325         int nl = (size+sizeof(int)-1)/sizeof(int);
326         BigNumDigit d;
327         int i,j,k=size-1;
328
329         for(i=0;i<(nl-1);i++){
330             d = 0;
331             for(j=0;j<sizeof(int);j++)
332               d |= (BigNumDigit)(stream[k-j]&0xff)<<(j*8);
333             BnnSetDigit(value+i,d);
334             k-=sizeof(int);
335           }
336 /* assert: i = nl-1 */
337         d=0;
338         BnnSetToZero(value+i,1);
339         nl=(size+sizeof(int)-1)%sizeof(int);
340         for(j=0;j<=nl;j++)
341               d |= (BigNumDigit)(stream[k-j]&0xff)<<(j*8);
342         BnnSetDigit(value+i,d);
343
344         return(stream+size);
345 }
346
347 /* 
348  * DecodePublic.  Initializes RSAKeyStorage. 
349  * Returns pointer to next element if no syntax problems, else zero.
350  */
351 unsigned char *DecodePublic (input, keys)
352 unsigned char *input;
353 RSAKeyStorage *keys;
354 {
355         register len;
356         unsigned char *next=input;
357
358         memset(keys,0,sizeof(RSAKeyStorage));
359
360         if ((*input != SEQUENCE_TAG)|| /* must be definite form */
361             (DecodeValueLength(input+1)<=0))  goto syntax_error;
362         input += DecodeHeaderLength(input);
363
364         if (*input != INTEGER_TAG) goto syntax_error;
365         len = DecodeValueLength(input+1);
366         if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
367         input+= DecodeHeaderLength(input);
368         input = DecodeBigInteger (input, keys->n, len);
369         keys->nl = 1 + BnnNumDigits(keys->n, (len+sizeof(int)-1)/sizeof(int));
370
371         if (*input != INTEGER_TAG) goto syntax_error;
372         len = DecodeValueLength(input+1);
373         if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
374         input+= DecodeHeaderLength(input);
375         input = DecodeBigInteger (input, keys->e, len);
376         keys->el = BnnNumDigits(keys->e, (len+sizeof(int)-1)/sizeof(int));
377
378         /* 
379          * should be at the end of the encoded substring
380          */
381         if (input != next+DecodeTotalLength(next)) goto syntax_error ;
382         
383         FinishKey(keys);
384
385         return(input);
386
387 syntax_error:
388 #ifdef DEBUG
389 printf("\nDecodePublic: Syntax Error.\n");
390 #endif
391         return(0);
392 }
393
394 /* 
395  * DecodePrivate.  Returns pointer to next element if good, else zero.
396  *
397  * Fills in RSAKeyStorage with key parameters if succesful, 
398  * assuming there is enough to go on.  The modulus can be supplied in the structure
399  * already, but other values are assumed cleared as necessary.  The idea
400  * in this case is to call with the same structure as the public key is in to
401  * make it into a private key structure based on decoding the prime p.
402  */
403 unsigned char *DecodePrivate (input, keys)
404 unsigned char *input;
405 RSAKeyStorage *keys;
406 {
407         int len, crl ;
408         unsigned char *next=input;
409         BigNum x;
410         
411         if ((*input != SEQUENCE_TAG)|| /* must be definite form */
412             (DecodeValueLength(input+1)<=0))  goto syntax_error;
413         input += DecodeHeaderLength(input);
414
415         if (*input == INTEGER_TAG) { /* must have a p */
416                 len = DecodeValueLength(input+1);
417                 if ((len<=0)||(len >= sizeof(BigNumDigit)*PrimeSize)) goto syntax_error;
418                 input+= DecodeHeaderLength(input);
419                 input = DecodeBigInteger (input, keys->p, len);
420                 len = keys->pl = BnnNumDigits(x=keys->p, (len+sizeof(int)-1)/sizeof(int));
421                 if ((x[len-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
422                         if (len<PrimeSize) keys->pl = len+1;
423                         else goto syntax_error ;
424         } else goto syntax_error ;
425
426         if (*input == CONTEXT_0_TAG) {  /* may have a q */
427                 len = DecodeValueLength(input+1);
428                 if ((len<=0)||(len >= sizeof(BigNumDigit)*PrimeSize)) goto syntax_error;
429                 input+= DecodeHeaderLength(input);
430                 input = DecodeBigInteger (input, keys->q, len);
431                 len= keys->ql = BnnNumDigits(x=keys->q, (len+sizeof(int)-1)/sizeof(int));
432                 if ((x[len-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
433                         if (len<PrimeSize) keys->ql = len+1;
434                         else goto syntax_error ;
435         }
436         else keys->ql=0;
437                
438         if (*input == CONTEXT_1_TAG) { /* may have a modulus */
439                 memset(keys->n,0,sizeof(*keys->n));
440                 len = DecodeValueLength(input+1);
441                 if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
442                 input+= DecodeHeaderLength(input);
443                 input = DecodeBigInteger (input, keys->n, len);
444                 keys->nl = 1 + BnnNumDigits(keys->n, (len+sizeof(int)-1)/sizeof(int));
445         }
446         
447         memset(keys->e,0,sizeof(*keys->e));
448         if (*input == CONTEXT_2_TAG) { /* may have an exponent */
449                 len = DecodeValueLength(input+1);
450                 if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
451                 input+= DecodeHeaderLength(input);
452                 input = DecodeBigInteger (input, keys->e, len);
453         } 
454         else  /* use default exponent */
455                 BnnSetDigit(keys->e, (BigNumDigit) ((1<<16)+1) );  /* 32 bits */
456         keys->el = BnnNumDigits(keys->e, (len+sizeof(int)-1)/sizeof(int));
457
458         memset(keys->dp,0,sizeof(*keys->dp));
459         if (*input == CONTEXT_3_TAG) { /* may have a dp */
460                 len = DecodeValueLength(input+1);
461                 if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
462                 input+= DecodeHeaderLength(input);
463                 input = DecodeBigInteger (input, keys->dp, len);
464                 keys->dpl = BnnNumDigits(keys->dp, (len+sizeof(int)-1)/sizeof(int));
465         }
466         else    keys->dpl=0;
467
468         memset(keys->dq,0,sizeof(*keys->dq));
469         if (*input == CONTEXT_4_TAG) { /* may have a dq */
470                 len = DecodeValueLength(input+1);
471                 if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
472                 input+= DecodeHeaderLength(input);
473                 input = DecodeBigInteger (input, keys->dq, len);
474                 keys->dql = BnnNumDigits(keys->dq, (len+sizeof(int)-1)/sizeof(int));
475         }
476         else    keys->dql=0;
477         
478         memset(keys->cr,0,sizeof(*keys->cr));
479         if (*input == CONTEXT_5_TAG) { /* may have a cr */
480                 len = DecodeValueLength(input+1);
481                 if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
482                 input+= DecodeHeaderLength(input);
483                 input = DecodeBigInteger (input, keys->cr, len);
484                 crl = 1;
485         }
486         else    crl=0;
487         
488         /* 
489          * should be at the end of the encoded substring
490          */
491         if (input != next+DecodeTotalLength(next)) goto syntax_error ;
492         
493         if (keys->ql == 0)              /* need to regenerate q */
494                 if (keys->nl == 0) goto syntax_error; /* must know n */
495                 else {
496                         BigNumDigit xx[4*DigitLim];
497                         int ql, pl, nl, i;
498                         
499                         memset(xx,0,sizeof(xx));
500                         BnnAssign(xx,keys->n,nl=keys->nl);
501                         BnnDivide(xx,nl,keys->p,pl=keys->pl);
502                         /* check that p evenly divided n */
503                         for(i=0;i<pl;i++) if(xx[i]) goto syntax_error;
504                         ql = keys->ql = BnnNumDigits(xx,nl) - pl;
505                         BnnAssign(keys->q,xx+pl,ql);
506                         if ((x[ql-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
507                                 if (ql<PrimeSize) keys->ql = ql+1;
508                                 else goto syntax_error ;
509                 }
510
511         if (keys->nl == 0){      /* need to regenerate n */
512                  int nl = keys->pl + keys->ql;
513                  memset(keys->n,0,sizeof(*keys->n));
514                  BnnMultiply(keys->n,nl,keys->p,keys->pl,keys->q,keys->ql);
515                  keys->nl=nl;
516         }
517
518         if(FinishKey(keys) == 0) goto syntax_error ;
519
520         return(input);
521 syntax_error:
522 #ifdef DEBUG
523 printf("\nDecodePrivate: Syntax Error.\n");
524 #endif
525 #ifndef DEBUG
526         memset(keys->p,0,sizeof(*keys->p));
527         memset(keys->q,0,sizeof(*keys->q));
528         memset(keys->dp,0,sizeof(*keys->dp));
529         memset(keys->dq,0,sizeof(*keys->dq));
530         memset(keys->cr,0,sizeof(*keys->cr));
531         keys->pl=keys->ql=keys->dpl=keys->dql=0;
532 #endif
533         return(0);
534 }
535
536 /* 
537  * DecodePrivateP.  Returns pointer to next element if good, else zero.
538  *
539  * Fills in RSAKeyStorage with key parameters if succesful, 
540  * assuming there is enough to go on.  The modulus can be supplied in the structure
541  * already, but other values are assumed cleared as necessary.  The idea
542  * in this case is to call with the same structure as the public key is in to
543  * make it into a private key structure based on decoding the prime p.
544  * Only the prime p must be passed in.
545  */
546 unsigned char *DecodePrivateP (input, keys)
547 unsigned char *input;
548 RSAKeyStorage *keys;
549 {
550         int len, crl ;
551         unsigned char *next=input;
552         BigNum x;
553         
554         if ((*input != SEQUENCE_TAG)|| /* must be definite form */
555             (DecodeValueLength(input+1)<=0))  goto syntax_error;
556         input += DecodeHeaderLength(input);
557
558         if (*input == INTEGER_TAG) { /* must have a p */
559                 len = DecodeValueLength(input+1);
560                 if ((len<=0)||(len >= sizeof(BigNumDigit)*PrimeSize)) goto syntax_error;
561                 input+= DecodeHeaderLength(input);
562                 input = DecodeBigInteger (input, keys->p, len);
563                 len = keys->pl = BnnNumDigits(x=keys->p, (len+sizeof(int)-1)/sizeof(int));
564                 if ((x[len-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
565                         if (len<PrimeSize) keys->pl = len+1;
566                         else goto syntax_error ;
567         } else goto syntax_error ;
568
569         if (*input == CONTEXT_0_TAG) goto syntax_error ;
570         else keys->ql=0;
571                
572         if (*input == CONTEXT_1_TAG) goto syntax_error ;
573         
574         memset(keys->e,0,sizeof(*keys->e));
575         if (*input == CONTEXT_2_TAG) goto syntax_error ;
576         else  /* use default exponent */
577                 BnnSetDigit(keys->e, (BigNumDigit) ((1<<16)+1) );  /* 32 bits */
578         keys->el = BnnNumDigits(keys->e, (len+sizeof(int)-1)/sizeof(int));
579
580         memset(keys->dp,0,sizeof(*keys->dp));
581         if (*input == CONTEXT_3_TAG) goto syntax_error ;
582         else    keys->dpl=0;
583
584         memset(keys->dq,0,sizeof(*keys->dq));
585         if (*input == CONTEXT_4_TAG) goto syntax_error ;
586         else    keys->dql=0;
587         
588         memset(keys->cr,0,sizeof(*keys->cr));
589         if (*input == CONTEXT_5_TAG) goto syntax_error ;
590         else    crl=0;
591         
592         /* 
593          * should be at the end of the encoded substring
594          */
595         if (input != next+DecodeTotalLength(next)) goto syntax_error ;
596         
597         if (keys->ql == 0)              /* need to regenerate q */
598                 if (keys->nl == 0) goto syntax_error; /* must know n */
599                 else {
600                         BigNumDigit xx[4*DigitLim];
601                         int ql, pl, nl, i;
602                         
603                         memset(xx,0,sizeof(xx));
604                         BnnAssign(xx,keys->n,nl=keys->nl);
605                         BnnDivide(xx,nl,keys->p,pl=keys->pl);
606                         /* check that p evenly divided n */
607                         for(i=0;i<pl;i++) if(xx[i]) goto syntax_error;
608                         ql = keys->ql = BnnNumDigits(xx,nl) - pl;
609                         BnnAssign(keys->q,xx+pl,ql);
610                         if ((x[ql-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
611                                 if (ql<PrimeSize) keys->ql = ql+1;
612                                 else goto syntax_error ;
613                 }
614
615         if (keys->nl == 0){      /* need to regenerate n */
616                  int nl = keys->pl + keys->ql;
617                  memset(keys->n,0,sizeof(*keys->n));
618                  BnnMultiply(keys->n,nl,keys->p,keys->pl,keys->q,keys->ql);
619                  keys->nl=nl;
620         }
621
622         if(FinishKey(keys) == 0) goto syntax_error ;
623
624         return(input);
625 syntax_error:
626 #ifdef DEBUG
627 printf("\nDecodePrivateP: Syntax Error.\n");
628 #endif
629 #ifndef DEBUG
630         memset(keys->p,0,sizeof(*keys->p));
631         memset(keys->q,0,sizeof(*keys->q));
632         memset(keys->dp,0,sizeof(*keys->dp));
633         memset(keys->dq,0,sizeof(*keys->dq));
634         memset(keys->cr,0,sizeof(*keys->cr));
635         keys->pl=keys->ql=keys->dpl=keys->dql=0;
636 #endif
637         return(0);
638 }
This page took 0.148486 seconds and 5 git commands to generate.