|
|
1.1 ! root 1: RSAREF(TM): ! 2: A Cryptographic Toolkit for Privacy-Enhanced Mail ! 3: Library Reference Manual ! 4: ! 5: RSA Laboratories ! 6: March 2, 1992 ! 7: ! 8: Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data ! 9: Security, Inc. All rights reserved. ! 10: ! 11: ! 12: INTRODUCTION ! 13: ! 14: This manual is a reference guide for users of RSAREF, a cryptographic ! 15: toolkit designed to facilitate rapid development of Internet ! 16: Privacy-Enhanced Mail (PEM) [1-3] implementations. ! 17: ! 18: RSAREF supports the following PEM-specified algorithms: ! 19: ! 20: - RSA encryption and key generation, as defined by RSA Data ! 21: Security's Public-Key Cryptography Standards (PKCS) [4] ! 22: - MD2 and MD5 message digests [3,5,6] ! 23: - DES (Data Encryption Standard) in cipher-block chaining mode ! 24: [7,8] ! 25: ! 26: RSAREF is written entirely in C. Its application interface includes ! 27: the following routines: ! 28: ! 29: R_SignPEMBlock computes a digital signature on a message ! 30: R_VerifyPEMSignature verifies a digital signature on a message ! 31: R_VerifyBlockSignature verifies a digital signature on a block of ! 32: data such as a certificate ! 33: ! 34: R_SealPEMBlock computes a digital signature and encrypts a ! 35: message ! 36: R_OpenPEMBlock decrypts an encrypted message and verifies a ! 37: digital signature ! 38: ! 39: R_DigestBlock computes a message digest on a message ! 40: ! 41: R_GeneratePEMKeys generates an RSA public/private key pair ! 42: ! 43: R_RandomInit initializes a random structure ! 44: R_RandomUpdate mixes bytes into a random structure ! 45: R_GetRandomBytesNeeded computes the number of mix-in bytes still ! 46: needed to seed a random structure ! 47: R_RandomFinal zeroizes a random structure ! 48: ! 49: A simple PEM implementation can be built directly on top of these ! 50: routines, together with message parsing and formatting routines and ! 51: certificate-management routines. ! 52: ! 53: This manual is divided into five main parts and three appendices. ! 54: ! 55: This part introduces RSAREF. The next three parts explain RSAREF ! 56: procedures: random structures; cryptographic enhancements; and ! 57: key-pair generation. The last part documents the platform-specific ! 58: run-time library. ! 59: ! 60: Appendix A lists RSAREF error types. Appendix B lists RSAREF types ! 61: and constants. Appendix C lists platform-specific types and ! 62: constants. ! 63: ! 64: RSAREF is intended to be compatible with forthcoming revised versions ! 65: of the PEM RFCs, which are now in the unofficial "Internet-Draft" ! 66: stage. ! 67: ! 68: ! 69: RANDOM STRUCTURES ! 70: ! 71: A random structure contains a seed from which a pseudorandom sequence ! 72: of bytes is derived. RSAREF generates keys and pads RSA encryption ! 73: blocks with bytes derived from a random structure. ! 74: ! 75: Random structures are used by both message-processing and ! 76: key-generation applications. ! 77: ! 78: RSAREF initializes a random structure with the procedure ! 79: R_RandomInit. A typical application calls R_RandomInit on entry. ! 80: ! 81: A new random structure is not ready for use until it is seeded by ! 82: mixing in some random bytes. RSAREF seeds a random structure with the ! 83: procedure R_RandomUpdate and R_GetRandomBytesNeeded. A random ! 84: structure is considered seeded when the number of bytes still needed ! 85: reaches zero. More bytes can be mixed in after the random structure ! 86: is seeded. A typical application calls R_GetRandomBytesNeeded and ! 87: R_RandomUpdate immediately after calling R_RandomInit. ! 88: ! 89: RSAREF zeroizes a random structure with the procedure R_RandomFinal. ! 90: A typical application calls R_RandomFinal on exit. ! 91: ! 92: ! 93: R_RandomInit ! 94: ! 95: int R_RandomInit ( ! 96: R_RANDOM_STRUCT *randomStruct /* new random structure */ ! 97: ); ! 98: ! 99: R_RandomInit initializes a new random structure, storing the result ! 100: in randomStruct. ! 101: ! 102: Return value: 0 success ! 103: nonzero reserved for future compatibility ! 104: ! 105: ! 106: R_RandomUpdate ! 107: ! 108: int R_RandomUpdate ( ! 109: R_RANDOM_STRUCT *randomStruct, /* random structure */ ! 110: unsigned char *block, /* block of values to mix in */ ! 111: unsigned int blockLen /* length of block */ ! 112: ); ! 113: ! 114: R_RandomUpdate mixes blockLen bytes from block into randomStruct. ! 115: ! 116: Return value: 0 success ! 117: nonzero reserved for future compatibility ! 118: ! 119: ! 120: R_GetRandomBytesNeeded ! 121: ! 122: int R_GetRandomBytesNeeded ( ! 123: unsigned int *bytesNeeded, /* number of mix-in bytes needed */ ! 124: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 125: ); ! 126: ! 127: R_GetRandomBytesNeeded computes the number of mix-in bytes still ! 128: needed to seed randomStruct, storing the result in bytesNeeded. ! 129: ! 130: Return value: 0 success ! 131: nonzero reserved for future compatibility ! 132: ! 133: ! 134: R_RandomFinal ! 135: ! 136: void R_RandomFinal ( ! 137: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 138: ); ! 139: ! 140: R_RandomFinal zeroizes randomStruct. ! 141: ! 142: No return value. ! 143: ! 144: ! 145: CRYPTOGRAPHIC ENHANCEMENTS ! 146: ! 147: RSAREF applies cryptographic enhancements to messages with six ! 148: procedures: R_SignPEMBlock, R_VerifyPEMSignature, ! 149: R_VerifyBlockSignature, R_SealPEMBlock, R_OpenPEMBlock, and ! 150: R_DigestBlock. ! 151: ! 152: The first five procedures are typically called by message-processing ! 153: applications. R_DigestBlock is typically called by key-generation ! 154: applications when computing the message digest of a prototype ! 155: certificate [2,9]. ! 156: ! 157: To sign a message, an application calls R_SignPEMBlock, giving these ! 158: arguments: ! 159: ! 160: - a pointer to the message content, and the message length ! 161: - an integer identifying which message-digest algorithm to apply ! 162: (MD2 or MD5) ! 163: - a flag indicating whether to encode the message in printable ! 164: ASCII according to RFC 1113 ! 165: - the signer's RSA private key ! 166: ! 167: R_SignPEMBlock signs the message with the signer's private key and ! 168: the specified message-digest algorithm, and optionally encodes the ! 169: message in printable ASCII. It returns the signature, possibly the ! 170: encoded message, and the status of the operation. The signature is ! 171: encoded according to RFC 1113. ! 172: ! 173: To verify a signature on a message, an application calls ! 174: R_VerifyPEMSignature, giving these arguments: ! 175: ! 176: - a pointer to the (possibly encoded) message, and the message ! 177: length ! 178: - a pointer to the signature, and the signature length ! 179: - an integer identifying which message-digest algorithm was applied ! 180: (MD2 or MD5) ! 181: - a flag indicating whether the message was encoded in printable ! 182: ASCII ! 183: - the signer's RSA public key ! 184: ! 185: R_VerifyPEMSignature decodes the message if it was encoded and ! 186: verifies the signature on the message with the signer's public key ! 187: and the specified message-digest algorithm. It returns the message ! 188: content if the message was encoded, and the status of the operation. ! 189: ! 190: To verify a signature on a block of data such as a certificate where ! 191: the signature is not encoded in printable ASCII, an application calls ! 192: R_VerifyBlockSignature, giving these arguments: ! 193: ! 194: - a pointer to the block, and the block length ! 195: - a pointer to the signature, and the signature length ! 196: - an integer identifying which message-digest algorithm was applied ! 197: (MD2 or MD5) ! 198: - the signer's RSA public key ! 199: ! 200: R_VerifyBlockSignature verifies the signature on the message with the ! 201: signer's public key and the specified message-digest algorithm. It ! 202: returns the status of the operation. ! 203: ! 204: To seal a message (sign and encrypt it), an application calls ! 205: R_SealPEMBlock, giving these arguments: ! 206: ! 207: - a pointer to the message content, and the message length ! 208: - an integer identifying which message-digest algorithm to apply ! 209: (MD2 or MD5) ! 210: - the signer's RSA private key ! 211: - the recipient's RSA public key ! 212: ! 213: R_SealPEMBlock signs the message with the signer's private key and ! 214: the specified message-digest algorithm, encrypts the message and the ! 215: signature with a random DES key, and encrypts the DES key with the ! 216: recipient's public key. It returns the encrypted message, the ! 217: encrypted key, the encrypted signature, the DES initialization ! 218: vector, and the status of the operation. The encrypted message, key, ! 219: and signature are encoded according to RFC 1113. ! 220: ! 221: To open a message (decrypt it and verify its signature), an ! 222: application calls R_OpenPEMBlock, giving these arguments: ! 223: ! 224: - a pointer to the encrypted message, and the encrypted message ! 225: length ! 226: - a pointer to the encrypted key, and the encrypted key length ! 227: - a pointer to the encrypted signature, and the encrypted signature ! 228: length ! 229: - a DES initialization vector ! 230: - an integer identifying which message-digest algorithm was applied ! 231: (MD2 or MD5) ! 232: - the signer's RSA public key ! 233: - the recipient's RSA private key ! 234: ! 235: R_OpenPEMBlock decrypts the encrypted DES key with the recipient's ! 236: private key, decrypts the encrypted message and the encrypted ! 237: signature with the DES key, and verifies the signature on the message ! 238: with the signer's public key and the specified message-digest ! 239: algorithm. It returns the message content and the status of the ! 240: operation. ! 241: ! 242: To digest a block of data such as a prototype certificate, an ! 243: application calls R_DigestBlock, giving these arguments: ! 244: ! 245: - a pointer to the block, and the block length ! 246: - an integer identifying which message-digest algorithm to apply ! 247: (MD2 or MD5) ! 248: ! 249: R_DigestBlock digests the block with the specified message-digest ! 250: algorithm. It returns the message digest and the status of the ! 251: operation. ! 252: ! 253: ENCODED_CONTENT_LEN, DECODED_CONTENT_LEN, ENCRYPTED_CONTENT_LEN, and ! 254: DECRYPTED_CONTENT_LEN are macros that assist in determining the ! 255: maximum lengths of the results of cryptographic enhancements. ! 256: ! 257: ! 258: R_SignPEMBlock ! 259: ! 260: int R_SignPEMBlock ( ! 261: unsigned char *encodedContent, /* encoded content */ ! 262: unsigned int *encodedContentLen, /* length of encoded content */ ! 263: unsigned char *encodedSignature, /* encoded signature */ ! 264: unsigned int *encodedSignatureLen, /* length of encoded signature */ ! 265: unsigned char *content, /* content */ ! 266: unsigned int contentLen, /* length of content */ ! 267: int recode, /* recoding flag */ ! 268: int digestAlgorithm, /* message-digest algorithm */ ! 269: R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ ! 270: ); ! 271: ! 272: R_SignPEMBlock computes a digital signature on content. Specifically, ! 273: R_SignPEMBlock performs the following steps: ! 274: ! 275: 1. It digests content with digestAlgorithm, giving a message ! 276: digest. ! 277: ! 278: 2. It encrypts the message digest with privateKey, giving a ! 279: digital signature, and encodes the result in printable ! 280: ASCII according to RFC 1113, storing the encoding in ! 281: encodedSignature. ! 282: ! 283: 3. If recode is nonzero, it encodes content in printable ASCII, ! 284: storing the encoding in encodedContent. ! 285: ! 286: If recode is nonzero, encodedContent will be an ASCII string, encoded ! 287: according to RFC 1113. (It will not contain any line delimiters; the ! 288: application must break the string into 64-character lines.) ! 289: encodedContentLen will not be greater than ! 290: ENCODED_CONTENT_LEN(contentLen). If recode is zero, encodedContent is ! 291: ignored. ! 292: ! 293: encodedSignature will be an ASCII string, encoded according to RFC ! 294: 1113. encodedSignatureLen will not be greater than ! 295: MAX_PEM_SIGNATURE_LEN. ! 296: ! 297: digestAlgorithm is the algorithm by which the content is digested. It ! 298: must be DA_MD2, which indicates the MD2 message-digest algorithm, or ! 299: DA_MD5, which indicates the MD5 message-digest algorithm. ! 300: ! 301: Return value: 0 success ! 302: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 303: RE_PRIVATE_KEY privateKey cannot encrypt message digest ! 304: ! 305: ! 306: R_VerifyPEMSignature ! 307: ! 308: int R_VerifyPEMSignature ( ! 309: unsigned char *content, /* content */ ! 310: unsigned int *contentLen, /* length of content */ ! 311: unsigned char *encodedContent, /* (possibly) encoded content */ ! 312: unsigned int encodedContentLen, /* length of encoded content */ ! 313: unsigned char *encodedSignature, /* encoded signature */ ! 314: unsigned int encodedSignatureLen, /* length of encoded signature */ ! 315: int recode, /* recoding flag */ ! 316: int digestAlgorithm, /* message-digest algorithm */ ! 317: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 318: ); ! 319: ! 320: R_VerifyPEMSignature verifies a digital signature on a message. Its ! 321: operation is the inverse of R_SignPEMBlock. R_VerifyPEMSignature ! 322: operates on encodedSignature and encodedContent. If recode is ! 323: nonzero, it first decodes encodedContent according to RFC 1113, and ! 324: stores the result in content. If recode is zero, content is ignored. ! 325: ! 326: If recode is nonzero, contentLen will not be greater than ! 327: DECODED_CONTENT_LEN(encodedContentLen). ! 328: ! 329: Return value: 0 success ! 330: RE_CONTENT_ENCODING encodedContent has RFC 1113 encoding error ! 331: RE_SIGNATURE_ENCODING encodedSignature has RFC 1113 encoding error ! 332: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 333: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 334: RE_SIGNATURE signature on content is incorrect ! 335: ! 336: ! 337: R_VerifyBlockSignature ! 338: ! 339: int R_VerifyBlockSignature ( ! 340: unsigned char *block, /* block */ ! 341: unsigned int blockLen, /* length of block */ ! 342: unsigned char *signature, /* signature */ ! 343: unsigned int signatureLen, /* length of signature */ ! 344: int digestAlgorithm, /* message-digest algorithm */ ! 345: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 346: ); ! 347: ! 348: R_VerifyBlockSignature verifies a digital signature on a block of ! 349: data such as a certificate. Its operation is similar to ! 350: R_VerifyPEMSignature, except that the block and signature are ! 351: arbitrary byte strings, rather than RFC 1113-encoded strings. ! 352: ! 353: Return value: 0 success ! 354: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 355: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 356: RE_SIGNATURE signature on block is incorrect ! 357: ! 358: ! 359: R_SealPEMBlock ! 360: ! 361: int R_SealPEMBlock ( ! 362: unsigned char *encryptedContent, /* encoded, encrypted content */ ! 363: unsigned int *encryptedContentLen, ! 364: /* length of encoded, encrypted content */ ! 365: unsigned char *encryptedKey, /* encoded, encrypted DES key */ ! 366: unsigned int *encryptedKeyLen, ! 367: /* length of encoded, encrypted DES key */ ! 368: unsigned char *encryptedSignature,/* encoded, encrypted signature */ ! 369: unsigned int *encryptedSignatureLen, ! 370: /* length of encoded, encrypted signature */ ! 371: unsigned char iv[8], /* DES initializing vector */ ! 372: unsigned char *content, /* content */ ! 373: unsigned int contentLen, /* length of content */ ! 374: int digestAlgorithm, /* message-digest algorithm */ ! 375: R_RSA_PUBLIC_KEY *publicKey, /* recipient's RSA public key */ ! 376: R_RSA_PRIVATE_KEY *privateKey, /* signer's RSA private key */ ! 377: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 378: ); ! 379: ! 380: R_SealPEMBlock computes a digital signature on content then encrypts ! 381: the content and the signature. Specifically, R_SealPEMBlock performs ! 382: the following steps: ! 383: ! 384: 1. It digests content with digestAlgorithm, giving a message ! 385: digest. ! 386: ! 387: 2. It encrypts the message digest with privateKey, giving a ! 388: digital signature. ! 389: ! 390: 3. It generates a random DES key and initializing vector, ! 391: storing the initializing vector in iv. ! 392: ! 393: 4. It encrypts content with the DES key and initializing vector ! 394: in cipher-block chaining mode, and encodes the result in ! 395: printable ASCII according to RFC 1113, storing the encoding ! 396: in encryptedContent. ! 397: ! 398: 5. It encrypts the DES key with publicKey and encodes the ! 399: result in printable ASCII, storing the encoding in ! 400: encryptedKey. ! 401: ! 402: 6. It encrypts the digital signature with the DES key and ! 403: initializing vector, and encodes the result in printable ! 404: ASCII, storing the encoding in encryptedSignature. ! 405: ! 406: encryptedContent will be an ASCII string, encoded according to RFC ! 407: 1113. (It will not contain any line delimiters; the application must ! 408: break the string into 64-character lines.) encryptedContentLen will ! 409: not be greater than ENCRYPTED_CONTENT_LEN(contentLen). ! 410: ! 411: encryptedKey and encryptedSignature will be ASCII strings, encoded ! 412: according to RFC 1113. encryptedKeyLen will not be greater than ! 413: MAX_PEM_ENCRYPTED_KEY_LEN. encryptedSignatureLen will not be greater ! 414: than MAX_PEM_ENCRYPTED_SIGNATURE_LEN. ! 415: ! 416: digestAlgorithm is the algorithm by which the content is digested. It ! 417: must be DA_MD2, which indicates the MD2 message-digest algorithm, or ! 418: DA_MD5, which indicates the MD5 message-digest algorithm. ! 419: ! 420: randomStruct must have been seeded. ! 421: ! 422: Return value: 0 success ! 423: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 424: RE_PRIVATE_KEY privateKey cannot encrypt message digest ! 425: RE_PUBLIC_KEY publicKey cannot encrypt DES key ! 426: RE_NEED_RANDOM randomStruct is not seeded ! 427: ! 428: ! 429: R_OpenPEMBlock ! 430: ! 431: int R_OpenPEMBlock ( ! 432: unsigned char *content, /* content */ ! 433: unsigned int *contentLen, /* length of content */ ! 434: unsigned char *encryptedContent, /* encoded, encrypted content */ ! 435: unsigned int encryptedContentLen, ! 436: /* length of encoded, encrypted content */ ! 437: unsigned char *encryptedKey, /* encoded, encrypted DES key */ ! 438: unsigned int encryptedKeyLen, ! 439: /* length of encoded, encrypted DES key */ ! 440: unsigned char *encryptedSignature,/* encoded, encrypted signature */ ! 441: unsigned int encryptedSignatureLen, ! 442: /* length of encoded, encrypted signature */ ! 443: unsigned char iv[8], /* DES initializing vector */ ! 444: int digestAlgorithm, /* message-digest algorithm */ ! 445: R_RSA_PRIVATE_KEY *privateKey, /* recipient's RSA private key */ ! 446: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 447: ); ! 448: ! 449: R_OpenPEMBlock decrypts an encrypted message and verifies a digital ! 450: signature. Its operation is the inverse of R_SealPEMBlock. ! 451: ! 452: contentLen will not be greater than ! 453: DECRYPTED_CONTENT_LEN(encryptedContentLen). ! 454: ! 455: Return value: 0 success ! 456: RE_CONTENT_ENCODING encryptedContent has RFC 1113 encoding error ! 457: RE_KEY_ENCODING encryptedKey has RFC 1113 encoding error ! 458: RE_SIGNATURE_ENCODING encryptedSignature has RFC 1113 encoding ! 459: error ! 460: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 461: RE_PRIVATE_KEY privateKey cannot decrypt encrypted key ! 462: RE_KEY recovered DES key cannot decrypt encrypted ! 463: content or encrypted signature ! 464: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 465: RE_SIGNATURE signature on content is incorrect ! 466: ! 467: ! 468: R_DigestBlock ! 469: ! 470: int R_DigestBlock ( ! 471: unsigned char *digest, /* message digest */ ! 472: unsigned int *digestLen, /* length of message digest */ ! 473: unsigned char *content, /* content */ ! 474: unsigned int contentLen, /* length of content */ ! 475: int digestAlgorithm /* message-digest algorithm */ ! 476: ); ! 477: ! 478: R_DigestBlock computes a message digest on content, storing the ! 479: resulting message digest in digest and its length in digestLen. ! 480: ! 481: digestAlgorithm is the algorithm by which the content is digested. It ! 482: must be DA_MD2, which indicates the MD2 message-digest algorithm, or ! 483: DA_MD5, which indicates the MD5 message-digest algorithm. ! 484: ! 485: digestLen will not be greater than MAX_DIGEST_LEN. ! 486: ! 487: Return value: 0 success ! 488: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 489: ! 490: ! 491: KEY-PAIR GENERATION ! 492: ! 493: RSAREF generates key pairs with the procedure R_GeneratePEMKeys. ! 494: R_GeneratePEMKeys is typically called by key generation applications. ! 495: To generate a new key pair, an application calls R_GeneratePEMKeys, ! 496: giving the length of the modulus, the choice of exponent (F4 or F0), ! 497: and a random structure. R_GeneratePEMKeys generates an RSA key pair ! 498: and returns the status of the operation. ! 499: ! 500: ! 501: R_GeneratePEMKeys ! 502: ! 503: int R_GeneratePEMKeys ( ! 504: R_RSA_PUBLIC_KEY *publicKey, /* new RSA public key */ ! 505: R_RSA_PRIVATE_KEY *privateKey, /* new RSA private key */ ! 506: R_RSA_PROTO_KEY *protoKey, /* RSA prototype key */ ! 507: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 508: ); ! 509: ! 510: R_GeneratePEMKeys generates a random RSA key pair, storing the ! 511: resulting RSA public key in publicKey and the resulting RSA private ! 512: key in privateKey. ! 513: ! 514: Other parameters are as follows: ! 515: ! 516: protoKey The RSA prototype key specifying the length ! 517: in bits of the RSA modulus and the public ! 518: exponent. (See Appendix B.) ! 519: ! 520: randomStruct Random structure from which the key pair is ! 521: derived. It must have been seeded. ! 522: ! 523: Return value: 0 success ! 524: RE_MODULUS_LEN modulus length invalid ! 525: RE_NEED_RANDOM randomStruct is not seeded ! 526: ! 527: ! 528: RUN-TIME LIBRARY ! 529: ! 530: RSAREF operates on memory blocks with three platform-specific library ! 531: procedures that are modeled after conventional C library functions: ! 532: ! 533: R_memcmp compares two blocks of memory ! 534: R_memcpy copies a block of memory ! 535: R_memset sets a block of memory to a given value ! 536: ! 537: These procedures can be found in the file 'r_stdlib.c'. ! 538: ! 539: ! 540: R_memcmp ! 541: ! 542: int R_memcmp ( ! 543: POINTER firstBlock, /* first block */ ! 544: POINTER secondBlock, /* second block */ ! 545: unsigned int len /* length of blocks */ ! 546: ); ! 547: ! 548: R_memcmp compares the first len bytes of firstBlock and secondBlock. ! 549: The value of len can be zero, in which case firstBlock and secondBlock ! 550: are undefined and R_memcmp returns 0. R_memcmp compares the blocks by ! 551: scanning the blocks from lowest address to highest until a difference ! 552: is found. The smaller-valued block is the one with the smaller-valued ! 553: byte at the point of difference. If no difference is found, the ! 554: blocks are equal. ! 555: ! 556: Return value: < 0 firstBlock is smaller ! 557: 0 blocks are equal ! 558: > 0 firstBlock is larger ! 559: ! 560: ! 561: R_memcpy ! 562: ! 563: void R_memcpy ( ! 564: POINTER output, /* output block */ ! 565: POINTER input, /* input block */ ! 566: unsigned int len /* length of blocks */ ! 567: ); ! 568: ! 569: R_memcpy copies the first len bytes of input to output. The value of ! 570: len can be zero, in which output and input are undefined. The blocks ! 571: do not overlap. ! 572: ! 573: No return value. ! 574: ! 575: ! 576: R_memset ! 577: ! 578: void R_memset ( ! 579: POINTER output, /* output block */ ! 580: int value, /* value */ ! 581: unsigned int len /* length of block */ ! 582: ); ! 583: ! 584: R_memset sets the first len bytes of output to value. The value of ! 585: len is zero, in which case output is undefined. ! 586: ! 587: No return value. ! 588: ! 589: ! 590: APPENDIX A: RSAREF ERROR TYPES ! 591: ! 592: This appendix lists RSAREF's error types. ! 593: ! 594: RE_CONTENT_ENCODING content or encrypted content has RFC 1113 ! 595: encoding error ! 596: ! 597: RE_DIGEST_ALGORITHM message-digest algorithm is invalid ! 598: ! 599: RE_KEY recovered DES key cannot decrypt encrypted ! 600: content or encrypted signature ! 601: ! 602: RE_KEY_ENCODING encrypted key has RFC 1113 encoding error ! 603: ! 604: RE_MODULUS_LEN modulus length is invalid ! 605: ! 606: RE_NEED_RANDOM random structure is not seeded ! 607: ! 608: RE_PRIVATE_KEY private key cannot encrypt message digest, ! 609: or cannot decrypt encrypted key ! 610: ! 611: RE_PUBLIC_KEY public key cannot encrypt DES key, or cannot ! 612: decrypt signature ! 613: ! 614: RE_SIGNATURE signature on content or block is incorrect ! 615: ! 616: RE_SIGNATURE_ENCODING signature or encrypted signature has RFC 1113 ! 617: encoding error ! 618: ! 619: ! 620: APPENDIX B: RSAREF TYPES ! 621: ! 622: This appendix lists three RSAREF types: R_RSA_PUBLIC_KEY, ! 623: R_RSA_PRIVATE_KEY, and R_RSA_PROTO_KEY. ! 624: ! 625: ! 626: R_RSA_PUBLIC_KEY ! 627: ! 628: typedef struct { ! 629: unsigned int bits; /* length in bits of modulus */ ! 630: unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ ! 631: unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ ! 632: } R_RSA_PUBLIC_KEY; ! 633: ! 634: An R_RSA_PUBLIC_KEY value is a structure specifying an RSA public key. ! 635: There are three fields: ! 636: ! 637: bits length in bits of the modulus (not less than ! 638: MIN_RSA_MODULUS_BITS and not greater than ! 639: MAX_RSA_MODULUS_BITS) ! 640: ! 641: modulus modulus n, represented as a ! 642: MAX_RSA_MODULUS_LEN-byte number, most ! 643: significant byte first, as many leading zero ! 644: bytes as necessary ! 645: ! 646: exponent public exponent e, represented like modulus ! 647: ! 648: ! 649: R_RSA_PRIVATE_KEY ! 650: ! 651: typedef struct { ! 652: unsigned int bits; /* length in bits of modulus */ ! 653: unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ ! 654: unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; ! 655: /* public exponent */ ! 656: unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ ! 657: unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ ! 658: unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; ! 659: /* exponents for CRT */ ! 660: unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */ ! 661: } R_RSA_PRIVATE_KEY; ! 662: ! 663: An R_RSA_PRIVATE_KEY value is a structure specifying an RSA private ! 664: key. There are seven fields: ! 665: ! 666: bits length in bits of the modulus (not less than ! 667: MIN_RSA_MODULUS_BITS and not greater than ! 668: MAX_RSA_MODULUS_BITS) ! 669: ! 670: modulus modulus n, represented as a ! 671: MAX_RSA_MODULUS_LEN-byte number, most ! 672: significant byte first, as many leading zero ! 673: bytes as necessary ! 674: ! 675: publicExponent public exponent e, represented like modulus ! 676: ! 677: exponent private exponent d, represented like modulus ! 678: ! 679: prime prime factors p and q of modulus, each ! 680: represented as MAX_RSA_PRIME_LEN-byte ! 681: numbers, most significant byte first, as ! 682: many leading zero bytes as necessary, where ! 683: p > q ! 684: ! 685: primeExponents exponents (d mod p-1) and (d mod q-1) for ! 686: Chinese remainder theorem (CRT) operations, ! 687: each represented like prime factors ! 688: ! 689: coefficient coefficient (q^{-1} mod p) for Chinese ! 690: remainder theorem operations, represented ! 691: like prime factors ! 692: ! 693: ! 694: R_RSA_PROTO_KEY ! 695: ! 696: /* RSA prototype key. ! 697: */ ! 698: typedef struct { ! 699: unsigned int bits; /* length in bits of modulus */ ! 700: int useFermat4; /* public exponent (1 = F4, 0 = 3) */ ! 701: } R_RSA_PROTO_KEY; ! 702: ! 703: An R_RSA_PROTO_KEY value is a structure specifying the length in bits ! 704: of the RSA modulus and the public exponent for key-pair generation. ! 705: There are two fields: ! 706: ! 707: bits length in bits of the modulus (not less than ! 708: MIN_RSA_MODULUS_BITS and not greater than ! 709: MAX_RSA_MODULUS_BITS) ! 710: ! 711: useFermat4 a flag specifying the public exponent. If ! 712: nonzero, it specifies F4 (65537); if 0, F0 ! 713: (3) ! 714: ! 715: ! 716: APPENDIX C: PLATFORM-SPECIFIC TYPES AND CONSTANTS ! 717: ! 718: This appendix lists three platform-specific types and one #define'd ! 719: constant. ! 720: ! 721: ! 722: TYPES ! 723: ! 724: RSAREF requires three platform-specific types: POINTER, UINT2, and ! 725: UINT4. These are defined in the file 'global.h'. ! 726: ! 727: ! 728: POINTER ! 729: ! 730: A POINTER value is a generic pointer to memory to which any other ! 731: pointer can be cast. ! 732: ! 733: Example: ! 734: ! 735: typedef unsigned char *POINTER; ! 736: ! 737: ! 738: UINT2 ! 739: ! 740: A UINT2 value is a 16-bit unsigned integer. ! 741: ! 742: Example: ! 743: ! 744: typedef unsigned short int UINT2; ! 745: ! 746: ! 747: UINT4 ! 748: ! 749: A UINT4 value is a 32-bit unsigned integer. ! 750: ! 751: Example: ! 752: ! 753: typedef unsigned long int UINT4; ! 754: ! 755: ! 756: #DEFINE'D CONSTANTS ! 757: ! 758: RSAREF requires one #define'd constant: PROTOTYPES. This is defined ! 759: in the 'makefile' on the C compiler command line. ! 760: ! 761: PROTOTYPES indicates the form that C function declarations are to ! 762: take. If PROTOTYPES is nonzero, declarations take the form ! 763: ! 764: type function (type, ..., type); ! 765: ! 766: Otherwise declarations take the form ! 767: ! 768: type function (); ! 769: ! 770: ! 771: REFERENCES ! 772: ! 773: [1] J. Linn. RFC 1113: Privacy Enhancement for Internet Electronic ! 774: Mail: Part I -- Message Encipherment and Authentication ! 775: Procedures. Internet Activities Board, August 1989. ! 776: ! 777: [2] S. Kent and J. Linn. RFC 1114: Privacy Enhancement for Internet ! 778: Electronic Mail: Part II -- Certificate-Based Key Management. ! 779: Internet Activities Board, August 1989. ! 780: ! 781: [3] J. Linn. RFC 1115: Privacy Enhancement for Internet Electronic ! 782: Mail: Part III -- Algorithms, Modes, and Identifiers. Internet ! 783: Activities Board, August 1989. ! 784: ! 785: [4] RSA Data Security, Inc. PKCS #1: RSA Encryption Standard. Version ! 786: 1.4, June 1991. Also published as NIST/OSI Implementors Workshop ! 787: SEC-SIG-91-18, June 1991. (Available by anonymous FTP from ! 788: 'rsa.com' as 'pub/pkcs/pkcs-1.ps'.) ! 789: ! 790: [5] B.S. Kaliski Jr. The MD2 Message-Digest Algorithm. July 1, 1991. ! 791: (Available by anonymous FTP from 'rsa.com' as 'pub/md2.doc'.) ! 792: ! 793: [6] Ronald L. Rivest. The MD5 Message-Digest Algorithm. In ! 794: preparation. (Earlier version available by anonymous FTP from ! 795: 'rsa.com' as 'pub/md5.doc'.) ! 796: ! 797: [7] National Bureau of Standards. FIPS Publication 46-1: Data ! 798: Encryption Standard. January 1988. ! 799: ! 800: [8] National Bureau of Standards. FIPS Publication 81: DES Modes of ! 801: Operation. December 1980. ! 802: ! 803: [9] B.S. Kaliski Jr. Privacy Enhancement for Internet Electronic ! 804: Mail: Part IV: Notary, Co-Issuer, CRL-Storing, and ! 805: CRL-Retrieving Services. Draft, July 1, 1991. (Available by ! 806: anonymous FTP from 'rsa.com' as 'pub/forms.doc'.)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.