|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.