Annotation of pgp/src/rsaio.c, revision 1.1.1.1

1.1       root        1: /*     C source code for RSA library I/O routines.
                      2:        Implemented Nov 86 by Philip Zimmermann
                      3:        Last revised 11 Apr 91 by PRZ
                      4: 
                      5:        Boulder Software Engineering
                      6:        3021 Eleventh Street
                      7:        Boulder, CO 80304
                      8:        (303) 444-4541
                      9: 
                     10:        (c) Copyright 1986 by Philip Zimmermann.  All rights reserved.
                     11:        The author assumes no liability for damages resulting from the use 
                     12:        of this software, even if the damage results from defects in this 
                     13:        software.  No warranty is expressed or implied.  
                     14: 
                     15:        The external data representation for RSA messages and keys that
                     16:        some of these library routines assume is outlined in a paper by 
                     17:        Philip Zimmermann, "A Proposed Standard Format for RSA Cryptosystems",
                     18:        IEEE Computer, September 1986, Vol. 19 No. 9, pages 21-34.
                     19:        Some revisions to this data format have occurred since the paper
                     20:        was published.
                     21: */
                     22: 
                     23: /* #define DEBUG */
                     24: 
                     25: 
                     26: #ifndef EMBEDDED       /* not EMBEDDED - not compiling for embedded target */
                     27: #include <stdio.h>     /* for printf, etc. */
                     28: #else  /* EMBEDDED - compiling for embedded target */
                     29: #define NULL (void *)0
                     30: #endif
                     31: 
                     32: #include "rsalib.h"
                     33: #define RSAIO
                     34: #include "rsaio.h"
                     35: 
                     36: 
                     37: /*----------------- Following procedures relate to I/O ------------------*/
                     38: 
                     39: int string_length(char *s)
                     40:        /* Returns string length, just like strlen() from <string.h> */
                     41: {      int i;
                     42:        i = 0;
                     43:        while (*s++) i++;
                     44:        return (i);     
                     45: }      /* string_length */
                     46: 
                     47: 
                     48: static int ctox(int c)
                     49:        /* Returns integer 0-15 if c is an ASCII hex digit, -1 otherwise. */
                     50: {      if ((c >= '0') && (c <= '9'))
                     51:                return(c - '0');
                     52:        if ((c >= 'a') && (c <= 'f'))
                     53:                return((c - 'a') + 10);
                     54:        if ((c >= 'A') && (c <= 'F'))
                     55:                return((c - 'A') + 10);
                     56:        return(-1);             /* error -- not a hex digit */
                     57: }      /* ctox */
                     58: 
                     59: 
                     60: int str2reg(unitptr reg,string digitstr)
                     61:        /* Converts a possibly-signed digit string into a large binary number.
                     62:           Returns assumed radix, derived from suffix 'h','o',b','.' */
                     63: {      unit temp[MAX_UNIT_PRECISION],base[MAX_UNIT_PRECISION];
                     64:        int c,i;
                     65:        boolean minus = FALSE;
                     66:        short radix;    /* base 2-16 */
                     67: 
                     68:        mp_init(reg,0);
                     69:        
                     70:        i = string_length(digitstr);
                     71:        if (i==0) return(10);           /* empty string, assume radix 10 */
                     72:        c = digitstr[i-1];              /* get last char in string */
                     73:        
                     74:        switch (c)      /* classify radix select suffix character */
                     75:        {
                     76:        case '.':       radix = 10;
                     77:                        break;
                     78:        case 'H':
                     79:        case 'h':       radix = 16;
                     80:                        break;
                     81:        case 'O': 
                     82:        case 'o':       radix = 8;
                     83:                        break;
                     84:        case 'B':
                     85:        case 'b':       radix = 2;      /* caution! 'b' is a hex digit! */
                     86:                        break;
                     87:        default:        radix = 10;
                     88:        }
                     89: 
                     90:        mp_init(base,radix);
                     91:        if (minus = (*digitstr == '-')) digitstr++;
                     92:        while (c = *digitstr++)
                     93:        {       if (c==',') continue;   /* allow commas in number */
                     94:                c = ctox(c);
                     95:                if ((c < 0) || (c >= radix)) 
                     96:                        break;  /* scan terminated by any non-digit */
                     97:                mp_mult(temp,reg,base);
                     98:                mp_move(reg,temp);
                     99:                mp_init(temp,c);
                    100:                mp_add(reg,temp);
                    101:        }
                    102:        if (minus) mp_neg(reg);
                    103:        return(radix);
                    104: } /* str2reg */
                    105: 
                    106: 
                    107: /*     These I/O functions, such as putstr, puthexbyte, and puthexw16, 
                    108:        are provided here to avoid the need to link in printf from the 
                    109:        C I/O library.  This is handy in an embedded application.
                    110: */
                    111: 
                    112: #ifdef EMBEDDED                /* if compiling for embedded target */
                    113: int putchar(int c)     /* standard C library function */
                    114: {      /* stub -- replace with putchar suitable for embedded target. */
                    115: }      /* putchar */
                    116: #endif /* if compiling for embedded target */
                    117: 
                    118: void putstr(string s)
                    119:        /* Put out null-terminated ASCII string via putchar. */
                    120: {      while (*s) putchar(*s++);
                    121: }      /* putstr */
                    122: 
                    123: void puthexbyte(byte b)
                    124:        /* Put out byte in ASCII hex via putchar. */
                    125: {      static const char *nibs = "0123456789ABCDEF";
                    126:        putchar(nibs[b >> 4]);
                    127:        putchar(nibs[b & 0x0F]);
                    128: }      /* puthexbyte */
                    129: 
                    130: void puthexw16(word16 w)
                    131:        /* Put out 16-bit word in hex, high byte first. */
                    132: {      puthexbyte((byte)(w >> 8));
                    133:        puthexbyte((byte)(w & 0xFF));
                    134: }      /* puthexw16 */
                    135: 
                    136: #ifdef UNIT32
                    137: static void puthexw32(word32 lw)
                    138:        /* Puts out 32-bit word in hex, high byte first. */
                    139: {      puthexw16((word16)(lw>>16));
                    140:        puthexw16((word16)(lw & 0xFFFFL));
                    141: }      /* puthexw32 */
                    142: #endif /* UNIT32 */
                    143: 
                    144: 
                    145: #ifdef UNIT8
                    146: #define puthexunit(u) puthexbyte(u)
                    147: #endif
                    148: #ifdef UNIT16
                    149: #define puthexunit(u) puthexw16(u)
                    150: #endif
                    151: #ifdef UNIT32
                    152: #define puthexunit(u) puthexw32(u)
                    153: #endif
                    154: 
                    155: 
                    156: void fill0(byteptr buf,word16 bytecount)
                    157:        /* Zero-fill the byte buffer. */
                    158: {      while (bytecount--) *buf++ = 0;
                    159: }      /* fill0 */
                    160: 
                    161: 
                    162: int display_in_base(string s,unitptr n,short radix)
                    163:        /* Display n in any base, such as base 10.  Returns number of digits. */
                    164:        /*      s is string to label the displayed register.
                    165:                n is multiprecision integer.
                    166:                radix is base, 2-16. 
                    167:        */
                    168: {
                    169:        char buf[MAX_BIT_PRECISION + (MAX_BIT_PRECISION/8) + 2];
                    170:        unit r[MAX_UNIT_PRECISION],quotient[MAX_UNIT_PRECISION];
                    171:        word16 remainder;
                    172:        char *bp = buf;
                    173:        char minus = FALSE;
                    174:        int places = 0;
                    175:        int commaplaces;        /* put commas this many digits apart */
                    176:        int i;
                    177: 
                    178:        /*      If string s is just an ESC char, don't print it.
                    179:                It's just to inhibit the \n at the end of the number.
                    180:        */
                    181:        if ((s[0] != '\033') || (s[1] != '\0'))
                    182:                putstr(s);
                    183: 
                    184:        if ( (radix < 2) || (radix > 16) )
                    185:        {       putstr("****\n");       /* radix out of range -- show error */
                    186:                return(-1);
                    187:        }
                    188:        commaplaces = (radix==10 ? 3 : (radix==16 ? 4 :
                    189:                        (radix==2 ? 8 : (radix==8 ? 8 : 1))));
                    190:        mp_move(r,n);
                    191:        if ((radix == 10) && mp_tstminus(r))
                    192:        {       minus = TRUE;
                    193:                mp_neg(r);      /* make r positive */
                    194:        }
                    195: 
                    196:        *bp = '\0';
                    197:        do      /* build backwards number string */
                    198:        {       if (++places>1)
                    199:                        if ((places % commaplaces)==1)
                    200:                                *++bp = ',';    /* 000,000,000,000 */
                    201:                remainder = mp_shortdiv(quotient,r,radix);
                    202:                *++bp = "0123456789ABCDEF" [remainder]; /* Isn't C wonderful? */
                    203:                mp_move(r,quotient);
                    204:        } while (testne(r,0));
                    205:        if (minus)
                    206:                *++bp = '-';
                    207:        
                    208:        if (commaplaces!=1)
                    209:                while ((++places % commaplaces) != 1)
                    210:                        *++bp = ' '; /* pad to line up commas */
                    211: 
                    212:        i = string_length(s);
                    213:        while (*bp)
                    214:        {       putchar(*bp);
                    215:                ++i;
                    216:                if ((*bp == ',') || commaplaces==1)
                    217:                        if (i > (72-commaplaces))
                    218:                        {       putchar('\n'); 
                    219:                                i=string_length(s); 
                    220:                                while (i--) putchar(' ');
                    221:                                i = string_length(s);
                    222:                        }
                    223:                bp--;
                    224:        }
                    225:        switch (radix)
                    226:        {       /* show suffix character to designate radix */
                    227:        case 10: /* decimal */
                    228:                putchar('.');
                    229:                break;
                    230:        case 16: /* hex */
                    231:                putchar('h');
                    232:                break;
                    233:        case 8: /* octal */
                    234:                putchar('o');
                    235:                break;
                    236:        case 2: /* binary */
                    237:                putchar('b');
                    238:                break;
                    239:        default: /* nonstandard radix */
                    240:                /* printf("(%d)",radix); */ ;   
                    241:        }
                    242: 
                    243:        if ((s[0] == '\033') && (s[1] == '\0'))
                    244:                putchar(' ');   /* supress newline */
                    245:        else putchar('\n');
                    246: 
                    247:        fill0(buf,sizeof(buf)); /* burn the evidence on the stack...*/
                    248:        /* Note that local stack arrays r and quotient are now 0 */
                    249:        return(places);
                    250: }      /* display_in_base */
                    251: 
                    252: 
                    253: void mp_display(string s,unitptr r)
                    254:        /* Display register r in hex, with prefix string s. */
                    255: {      short precision;
                    256:        int i,j;
                    257:        putstr(s);
                    258:        normalize(r,precision); /* strip off leading zeros */
                    259:        if (precision == 0)
                    260:        {       putstr(" 0\n");
                    261:                return;
                    262:        }
                    263:        make_msbptr(r,precision);
                    264:        i=0;
                    265:        while (precision--)
                    266:        {       if (!(i++ % (16/BYTES_PER_UNIT)))
                    267:                {       if (i>1)
                    268:                        {       putchar('\n'); 
                    269:                                j=string_length(s); 
                    270:                                while (j--) putchar(' ');
                    271:                        }
                    272:                }
                    273:                puthexunit(*r);
                    274:                putchar(' ');
                    275:                post_lowerunit(r);
                    276:        }
                    277:        putchar('\n');
                    278: }      /* mp_display */
                    279: 
                    280: 
                    281: word16 checksum(register byteptr buf, register word16 count)
                    282:        /* Returns checksum of buffer. */
                    283: {      word16 cs;
                    284:        cs = 0;
                    285:        while (count--) cs += *buf++;
                    286:        return(cs);
                    287: } /* checksum */
                    288: 
                    289: 
                    290: void cbc_xor(register unitptr dst, register unitptr src, word16 bytecount)
                    291:        /*      Performs the XOR necessary for RSA Cipher Block Chaining.
                    292:                The dst buffer ought to have 1 less byte of significance than 
                    293:                the src buffer.  Only the least significant part of the src 
                    294:                buffer is used.  bytecount is the size of a plaintext block.
                    295:        */
                    296: {      short nunits;   /* units of precision */
                    297:        nunits = bytes2units(bytecount)-1;
                    298:        make_lsbptr(dst,global_precision);
                    299:        while (nunits--)
                    300:        {       *dst ^= *post_higherunit(src);
                    301:                post_higherunit(dst);
                    302:                bytecount -= units2bytes(1);
                    303:        }
                    304:        /* on the last unit, don't xor the excess top byte... */
                    305:        *dst ^= (*src & (power_of_2(bytecount<<3)-1));
                    306: }      /* cbc_xor */
                    307: 
                    308: 
                    309: void hiloswap(byteptr r1,short numbytes)
                    310:        /* Reverses the order of bytes in an array of bytes. */
                    311: {      byteptr r2;
                    312:        byte b;
                    313:        r2 = &(r1[numbytes-1]);
                    314:        while (r1 < r2) 
                    315:        {       b = *r1; *r1++ = *r2; *r2-- = b;
                    316:        }
                    317: }      /* hiloswap */
                    318: 
                    319: 
                    320: #define byteglue(lo,hi) ((((word16) hi) << 8) + (word16) lo)
                    321: 
                    322: 
                    323: short mpi2reg(register unitptr r,register byteptr buf)
                    324: /*     Converts a multiprecision integer from the externally-represented 
                    325:        form of a byte array with a 16-bit bitcount in a leading length 
                    326:        word to the internally-used representation as a unit array.
                    327:        Converts to INTERNAL byte order.
                    328:        The same buffer address may be used for both r and buf.
                    329:        Returns number of units in result, or returns -1 on error.
                    330: */
                    331: {      byte buf2[MAX_BYTE_PRECISION];
                    332:        word16 bytecount, unitcount, zero_bytes, i;
                    333:        word16 lowcount,highcount;
                    334: 
                    335:        /* First, extract 16-bit bitcount prefix from first 2 bytes... */
                    336: #ifdef XHIGHFIRST
                    337:        highcount = *buf++;
                    338:        lowcount = *buf++;
                    339: #else
                    340:        lowcount = *buf++;
                    341:        highcount = *buf++;
                    342: #endif
                    343:        /* Convert bitcount to bytecount and unitcount... */    
                    344:        bytecount = bits2bytes(byteglue(lowcount,highcount));
                    345:        unitcount = bytes2units(bytecount);
                    346:        if (unitcount > global_precision)
                    347:        {       /* precision overflow during conversion. */
                    348:                return(-1);     /* precision overflow -- error return */
                    349:        }
                    350:        zero_bytes = units2bytes(global_precision) - bytecount;
                    351: 
                    352: #ifdef XHIGHFIRST
                    353:        fill0(buf2,zero_bytes);  /* fill leading zero bytes */
                    354:        i = zero_bytes;
                    355: #else
                    356:        fill0(buf2+bytecount,zero_bytes);  /* fill trailing zero bytes */
                    357:        i = 0;
                    358: #endif
                    359:        while (bytecount--) buf2[i++] = *buf++;
                    360: 
                    361:        convert_order(buf2);    /* convert to INTERNAL byte order */
                    362:        mp_move(r,(unitptr)buf2);
                    363:        mp_burn((unitptr)buf2); /* burn the evidence on the stack */
                    364:        return(unitcount);      /* returns unitcount of reg */
                    365: }      /* mpi2reg */
                    366: 
                    367: 
                    368: short reg2mpi(register byteptr buf,register unitptr r)
                    369: /*     Converts the multiprecision integer r from the internal form of 
                    370:        a unit array to the normalized externally-represented form of a 
                    371:        byte array with a leading 16-bit bitcount word in buf[0] and buf[1].
                    372:        This bitcount length prefix is exact count, not rounded up.
                    373:        Converts to EXTERNAL byte order.
                    374:        The same buffer address may be used for both r and buf.
                    375:        Returns the number of bytes of the result, not counting length prefix.
                    376: */
                    377: {      byte buf1[MAX_BYTE_PRECISION];
                    378:        byteptr buf2;
                    379:        short bytecount,bc;
                    380:        word16 bitcount;
                    381:        bitcount = countbits(r);
                    382:        bytecount = bits2bytes(bitcount);
                    383:        bc = bytecount; /* save bytecount for return */
                    384:        buf2 = buf1;
                    385:        mp_move((unitptr)buf2,r);
                    386:        convert_order(buf2);    /* convert to EXTERNAL byte order */
                    387: #ifdef XHIGHFIRST      
                    388:        /* Skip over leading zero bytes. */
                    389:        buf2 += (units2bytes(global_precision) - bytecount);
                    390:        *buf++ = bitcount >> 8;         /* store bitcount with high byte first */
                    391:        *buf++ = bitcount & 0xff;
                    392: #else
                    393:        *buf++ = bitcount & 0xff;       /* store bitcount with low byte first */
                    394:        *buf++ = bitcount >> 8;
                    395: #endif /* not XHIGHFIRST */
                    396: 
                    397:        while (bytecount--) *buf++ = *buf2++;
                    398: 
                    399:        mp_burn((unitptr)buf1); /* burn the evidence on the stack */
                    400:        return(bc);             /* returns bytecount of mpi, not counting prefix */
                    401: }      /* reg2mpi */
                    402: 
                    403: 
                    404: #ifdef DEBUG
                    405: 
                    406: void dumpbuf(string s, byteptr buf, int bytecount)
                    407:        /* Dump buffer in hex, with string label prefix. */
                    408: {      putstr(s);
                    409:        while (bytecount--)
                    410:        {       puthexbyte(*buf++);
                    411:                putchar(' ');
                    412:                if ((bytecount & 0x0f)==0)
                    413:                        putchar('\n');
                    414:        }
                    415: } /* dumpbuf */
                    416: 
                    417: void dump_unit_array(string s, unitptr r)
                    418: /*     Dump unit array r as a C array initializer, with string label prefix. 
                    419:        Array is dumped in native unit order.
                    420: */
                    421: {      int unitcount;
                    422:        unitcount = significance(r);
                    423:        putstr(s);
                    424:        putstr("\n{ ");
                    425:        while (unitcount--)
                    426:        {       putstr("0x");
                    427:                puthexunit(*r++);
                    428:                putchar(',');
                    429:                if (unitcount && ((unitcount & 0x07)==0))
                    430:                        putstr("\n  ");
                    431:        }
                    432:        putstr(" 0};\n");
                    433: } /* dump_unit_array */
                    434: 
                    435: #endif /* ifdef DEBUG */
                    436: 
                    437: 
                    438: /*
                    439: **     short preblock(outreg, inbuf, bytecount, modulus, cksbit, randompad)
                    440: **
                    441: **     A plaintext message must be converted into an integer less than
                    442: **     the modulus n.  We do this by making it 1 byte shorter than the
                    443: **     normalized modulus n.  Short blocks are left justified and padded.
                    444: **     The last pad byte is a count of how many pad bytes were required,
                    445: **     including itself.  Then the 16-bit checksum is appended.
                    446: **
                    447: **     When using very long keys, if there are more than 255 bytes 
                    448: **     of padding, the extra pad bytes will all be 0.  The first 
                    449: **     nonzero pad byte from the end will contain the count of the 
                    450: **     pad bytes preceding it, which should be 255 if there were more 
                    451: **     than 255 total pad bytes.
                    452: **
                    453: **     For example, suppose the 5-byte string "hello" were the plaintext
                    454: **     that needed preblocking, and the modulus was 11 bytes long, and
                    455: **     nonrandom padding with a 16-bit checksum was applied.  Here it is 
                    456: **     after preblocking, assuming an LSB-first external format:
                    457: **     (LSB)                              (MSB)
                    458: **     'h','e','l','l','o',1,2,3,low_checksum,high_checksum,0,<slop zeros>
                    459: **
                    460: **     But if XHIGHFIRST were defined, it would be blocked this way:
                    461: **              (MSB)                              (LSB)
                    462: **     <slop zeros>,0,'h','e','l','l','o',1,2,3,high_checksum,low_checksum
                    463: */
                    464: short preblock(unitptr outreg, byteptr inbuf, short bytecount,
                    465:        unitptr modulus, boolean cksbit, byteptr randompad)
                    466: /*     Converts plaintext block into form suitable for RSA encryption.
                    467:        Converts to INTERNAL byte order.
                    468:        Returns # of bytes remaining to process.  Note that the same buffer 
                    469:        address may be used for both outreg and inbuf.
                    470:        cksbit is TRUE iff checksum word should be appended to block.
                    471:        randompad is a pointer to a buffer of random pad bytes to use for 
                    472:        padding material, or NULL iff we want to use constant padding.
                    473: */
                    474: {      byte out[MAX_BYTE_PRECISION];
                    475:        byte pad;
                    476:        short i,byte_precision,leading_zeros,remaining,blocksize,padsize;
                    477:        short excess_pads;      /* number of trailing zeros in long pads */
                    478:        short startbyte;
                    479:        word16 chksum;
                    480: 
                    481:        byte_precision = units2bytes(global_precision);
                    482:        leading_zeros = byte_precision - countbytes(modulus) + 1;
                    483:        blocksize = byte_precision - leading_zeros - (2*cksbit);
                    484:        /* note that blocksize includes data plus pad bytes, if any */
                    485: 
                    486:        remaining = bytecount - blocksize;
                    487:        if (remaining>=0) 
                    488:                bytecount = blocksize;
                    489:        padsize = blocksize - bytecount;        /* bytes of padding */
                    490:        pad = 0;
                    491:        i = 0;
                    492: 
                    493: #ifdef XHIGHFIRST
                    494:        while (leading_zeros--) 
                    495:                out[i++] = 0;
                    496: #endif
                    497:        startbyte = i;
                    498:        while (bytecount--)             /* copy user data */
                    499:                out[i++] = *inbuf++;
                    500: 
                    501:        /* Handle pad lengths in excess of 255 bytes... */
                    502:        excess_pads = 0;
                    503:        if (padsize > 255) 
                    504:                excess_pads = padsize - 255;    /* compute spillage */
                    505:        padsize -= excess_pads; /* do not allow padsize > 255 */
                    506: 
                    507:        /* Perform either random padding or constant padding... */
                    508:        if (randompad != NULL)  /* random pad buffer provided? */ 
                    509:        {       while (padsize-- > 1)
                    510:                {       ++pad;
                    511:                        out[i++] = *randompad++; /* use random pad bytes */
                    512:                }
                    513:                padsize++;      /* correct last padsize-- */
                    514:        }       /* end of random padding */
                    515: 
                    516:        while ( padsize-- > 0 ) 
                    517:                out[i++] = ++pad;
                    518: 
                    519:        while (excess_pads--)   /* only if more than 255 pad bytes */
                    520:                out[i++] = 0;           /* excess padding is zeros */
                    521: 
                    522:        /* End of padding logic */
                    523: 
                    524:        if (cksbit) 
                    525:        {       chksum = checksum(out+startbyte,blocksize);
                    526: #ifdef XHIGHFIRST      
                    527:                out[i++] = chksum >> 8; /* store checksum with high byte first */
                    528:                out[i++] = chksum & 0xff;
                    529: #else
                    530:                out[i++] = chksum & 0xff; /* store checksum with low byte first */
                    531:                out[i++] = chksum >> 8;
                    532: #endif /* not XHIGHFIRST */
                    533:        }
                    534: 
                    535: #ifndef XHIGHFIRST
                    536:        while (leading_zeros--) 
                    537:                out[i++] = 0;
                    538: #endif
                    539:        mp_move(outreg,(unitptr)out);
                    540:        mp_burn((unitptr)out); /* burn the evidence on the stack */
                    541:        convert_order(outreg);  /* convert outreg to INTERNAL byte order */
                    542:        return(remaining);      /* less than 0 if there was padding */
                    543: }      /* preblock */
                    544: 
                    545: 
                    546: short postunblock(byteptr outbuf, unitptr inreg,
                    547:        unitptr modulus, boolean padded, boolean cksbit)
                    548: /*     Converts a just-decrypted RSA block back into unblocked plaintext form.
                    549:        Converts to EXTERNAL byte order.
                    550:        See the notes on preblocking in the preblock routine above.
                    551:        Note that outbuf must be at least as large as inreg.
                    552:        The same buffer address may be used for both outbuf and inreg.
                    553:        padded is TRUE iff block is expected to contain pad bytes.
                    554:        cksbit is TRUE iff block is expected to contain checksum word.
                    555:        Returns positive bytecount of plaintext, or negative error status.
                    556: */
                    557: {      short i,byte_precision,leading_zeros,bytecount,blocksize;
                    558:        word16 chksum,chksumlo,chksumhi;
                    559:        word16 padsize;
                    560: 
                    561:        byte_precision = units2bytes(global_precision);
                    562:        leading_zeros = byte_precision - countbytes(modulus) + 1;
                    563:        blocksize = byte_precision - leading_zeros - (2*cksbit);
                    564:        /* note that blocksize includes data plus pad bytes, if any */
                    565: 
                    566:        mp_move((unitptr)outbuf,inreg);
                    567:        convert_order(outbuf);  /* convert to EXTERNAL byte order */
                    568: 
                    569: #ifndef XHIGHFIRST
                    570: #define        STARTBYTE 0
                    571: #else
                    572: #define STARTBYTE leading_zeros
                    573: #endif
                    574:        if (cksbit)
                    575:        {
                    576: #ifdef XHIGHFIRST
                    577:                chksumhi = outbuf[STARTBYTE+blocksize];
                    578:                chksumlo = outbuf[STARTBYTE+blocksize+1];
                    579: #else
                    580:                chksumlo = outbuf[STARTBYTE+blocksize];
                    581:                chksumhi = outbuf[STARTBYTE+blocksize+1];
                    582: #endif
                    583:                chksum = byteglue(chksumlo,chksumhi);
                    584: 
                    585:                if ( chksum != checksum(outbuf+STARTBYTE,blocksize) )
                    586:                        return(-1);     /* return checksum error */
                    587:        }       /* checkum expected */
                    588: 
                    589:        padsize = 0;
                    590:        if (padded)
                    591:        {       i = STARTBYTE+blocksize-1;
                    592:                while (outbuf[i] == 0)  /* clip off null excess pad bytes */
                    593:                {       padsize++; i--;
                    594:                }
                    595:                padsize += outbuf[i];
                    596:        }
                    597: 
                    598:        if (padsize > blocksize)
                    599:        {       /* Error - pad count out of range. */
                    600:                padsize = 0; /* bogus padding means no padding */
                    601:                return(-2);     /* pad count out of range -- error return */
                    602:        }
                    603:        bytecount = blocksize - padsize;
                    604: 
                    605: #ifdef XHIGHFIRST
                    606:        i = 0;
                    607:        while (i++ < bytecount)
                    608:                outbuf[i-1] = outbuf[STARTBYTE+i-1];
                    609: #endif
                    610:        i = bytecount;
                    611:        while (i < byte_precision) 
                    612:                outbuf[i++] = 0;
                    613:        return(bytecount);      /* normal return */
                    614: #undef STARTBYTE
                    615: }      /* postunblock */
                    616: 
                    617: /****************** end of RSA I/O library ************************/
                    618: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.