|
|
1.1 ! root 1: RSAREF(TM): A Cryptographic Toolkit ! 2: Library Reference Manual ! 3: ! 4: RSA Laboratories ! 5: March 21, 1994 ! 6: ! 7: Version 2.0 ! 8: ! 9: Copyright (C) 1991-4 RSA Laboratories, a division of RSA Data ! 10: Security, Inc. All rights reserved. ! 11: ! 12: ! 13: 1. INTRODUCTION ! 14: ! 15: This manual is a reference guide for users of RSAREF, RSA ! 16: Laboratories' portable, educational, reference implementation of ! 17: cryptography. ! 18: ! 19: RSAREF supports the following algorithms: ! 20: ! 21: o RSA encryption and key generation [1], as defined by RSA ! 22: Laboratories' Public-Key Cryptography Standards (PKCS) [2] ! 23: ! 24: o MD2 and MD5 message digests [3,4] ! 25: ! 26: o DES (Data Encryption Standard) in cipher-block chaining mode ! 27: [5,6] ! 28: ! 29: o Diffie-Hellman key agreement [7], as defined by PKCS #3 [8] ! 30: ! 31: o DESX, RSA Data Security's efficient, secure DES enhancement ! 32: ! 33: o Triple-DES, for added security with three DES operations ! 34: ! 35: RSAREF is written entirely in C. Its application interface includes ! 36: the following routines: ! 37: ! 38: R_SignInit, computes a digital signature on data of ! 39: R_SignUpdate, arbitrary length, processing in parts ! 40: and R_SignFinal ! 41: ! 42: R_VerifyInit, verifies a digital signature, processing in ! 43: R_VerifyUpdate, parts ! 44: and R_VerifyFinal ! 45: ! 46: R_SealInit, creates a digital envelope on data of ! 47: R_SealUpdate, arbitrary length, processing in parts ! 48: and R_SealFinal ! 49: ! 50: R_OpenInit, opens a digital envelope, processing in ! 51: R_OpenUpdate, parts ! 52: and R_OpenFinal ! 53: ! 54: R_DigestInit, digests data of arbitrary length, processing ! 55: R_DigestUpdate, in parts ! 56: and R_DigestFinal ! 57: ! 58: R_EncodePEMBlock encodes a message in printable ASCII ! 59: according to RFC 1421 [9] ! 60: R_DecodePEMBlock decodes a message encoded according to RFC ! 61: 1421 ! 62: ! 63: R_GeneratePEMKeys generates an RSA public/private key pair ! 64: ! 65: R_RandomInit initializes a random structure ! 66: R_RandomUpdate mixes bytes into a random structure ! 67: R_GetRandomBytesNeeded computes the number of mix-in bytes still ! 68: needed to seed a random structure ! 69: R_RandomFinal zeroizes a random structure ! 70: ! 71: R_GenerateDHParams generates Diffie-Hellman parameters ! 72: R_SetupDHAgreement sets up a key agreement ! 73: R_ComputeDHAgreedKey computes the agreed-upon key ! 74: ! 75: An Internet Privacy-Enhanced Mail [9-12] implementation can be built ! 76: directly on top of these routines, together with message parsing and ! 77: formatting routines and certificate-management routines. ! 78: Implementations of PKCS #7 and #10 [13,14] can be built in a similar ! 79: manner. Other secure applications can be built on top of the ! 80: Diffie-Hellman routines. ! 81: ! 82: The following routines are supported for backward compatibility with ! 83: RSAREF 1.0: ! 84: ! 85: R_SignPEMBlock computes a digital signature on a message ! 86: R_SignBlock computes a digital signature on a block of ! 87: data such as a certificate ! 88: R_VerifyPEMSignature verifies a digital signature on a message ! 89: R_VerifyBlockSignature verifies a digital signature on a block of ! 90: data such as a certificate ! 91: ! 92: R_SealPEMBlock computes a digital signature and encrypts a ! 93: message ! 94: R_OpenPEMBlock decrypts an encrypted message and verifies a ! 95: digital signature ! 96: ! 97: R_DigestBlock computes the message digest of a message ! 98: ! 99: This manual is divided into eight sections and three appendices. ! 100: ! 101: This section introduces RSAREF. The next six sections explain RSAREF ! 102: procedures: random structures; cryptographic enhancements; printable ! 103: ASCII encoding and decoding; key-pair generation; Diffie-Hellman key ! 104: agreement; and version 1.0 routines. The last section documents the ! 105: platform-specific run-time library. ! 106: ! 107: Appendix A lists RSAREF error types. Appendix B lists RSAREF types ! 108: and constants. Appendix C lists platform-specific types and ! 109: constants. ! 110: ! 111: ! 112: 2. RANDOM STRUCTURES ! 113: ! 114: A random structure contains a seed from which a pseudorandom sequence ! 115: of bytes is derived. RSAREF generates keys and pads RSA encryption ! 116: blocks with bytes derived from a random structure. ! 117: ! 118: Random structures are used by both message-processing and ! 119: key-generation applications. ! 120: ! 121: RSAREF sets up a random structure with the procedure R_RandomInit. A ! 122: typical application calls R_RandomInit on entry. ! 123: ! 124: A new random structure is not ready for use until it is seeded by ! 125: mixing in some random bytes. RSAREF seeds a random structure with the ! 126: procedure R_RandomUpdate and R_GetRandomBytesNeeded. A random ! 127: structure is considered seeded when the number of bytes still needed ! 128: reaches zero. More bytes can be mixed in after the random structure ! 129: is seeded. A typical application calls R_GetRandomBytesNeeded and ! 130: R_RandomUpdate immediately after calling R_RandomInit. ! 131: ! 132: RSAREF zeroizes a random structure with the procedure R_RandomFinal. ! 133: A typical application calls R_RandomFinal on exit. ! 134: ! 135: ! 136: R_RandomInit ! 137: ! 138: int R_RandomInit ( ! 139: R_RANDOM_STRUCT *randomStruct /* new random structure */ ! 140: ); ! 141: ! 142: R_RandomInit sets up a new random structure. ! 143: ! 144: Return value: 0 success ! 145: nonzero reserved for future compatibility ! 146: ! 147: ! 148: R_RandomUpdate ! 149: ! 150: int R_RandomUpdate ( ! 151: R_RANDOM_STRUCT *randomStruct, /* random structure */ ! 152: unsigned char *block, /* block of values to mix in */ ! 153: unsigned int blockLen /* length of block */ ! 154: ); ! 155: ! 156: R_RandomUpdate mixes blockLen bytes from block into randomStruct. ! 157: ! 158: Return value: 0 success ! 159: nonzero reserved for future compatibility ! 160: ! 161: ! 162: R_GetRandomBytesNeeded ! 163: ! 164: int R_GetRandomBytesNeeded ( ! 165: unsigned int *bytesNeeded, /* number of mix-in bytes needed */ ! 166: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 167: ); ! 168: ! 169: R_GetRandomBytesNeeded computes the number of mix-in bytes still ! 170: needed to seed randomStruct, storing the result in bytesNeeded. ! 171: ! 172: Return value: 0 success ! 173: nonzero reserved for future compatibility ! 174: ! 175: ! 176: R_RandomFinal ! 177: ! 178: void R_RandomFinal ( ! 179: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 180: ); ! 181: ! 182: R_RandomFinal zeroizes randomStruct. ! 183: ! 184: No return value. ! 185: ! 186: ! 187: 3. CRYPTOGRAPHIC ENHANCEMENTS ! 188: ! 189: RSAREF's cryptographic enhancements fall into five groups: signing ! 190: data; verifying signatures; sealing data in digital envelopes; ! 191: opening digital envelopes; and digesting data. ! 192: ! 193: All the procedures process data in parts; it is not necessary for all ! 194: data to be stored in memory at once. ! 195: ! 196: ! 197: 3.1 Signing data ! 198: ! 199: RSAREF signs data with three procedures: R_SignInit, R_SignUpdate, ! 200: and R_SignFinal. These procedures are typically called by ! 201: message-processing applications, by key-generation applications when ! 202: constructing a PEM or PKCS certification request, and by ! 203: certification applications when signing a certificate. ! 204: ! 205: An application first calls R_SignInit, giving an integer specifying ! 206: which message-digest algorithm to apply (see Appendix D). R_SignInit ! 207: sets up a context for the signature operation, and returns the ! 208: context. ! 209: ! 210: The application then calls R_SignUpdate any number of times, giving ! 211: the context and the next data part. R_SignUpdate digests the part. ! 212: ! 213: After all the parts are supplied, the application calls R_SignFinal, ! 214: giving the context and the signer's RSA private key. R_SignFinal ! 215: encrypts the message digest with the private key and returns the ! 216: result, which is the signature. ! 217: ! 218: An application may call R_SignUpdate again after R_SignFinal to ! 219: sign other data, without setting up a new context. ! 220: ! 221: ! 222: R_SignInit ! 223: ! 224: int R_SignInit ( ! 225: R_SIGNATURE_CTX *context, /* new context */ ! 226: int digestAlgorithm /* message-digest algorithm */ ! 227: ); ! 228: ! 229: R_SignInit begins a signature operation, setting up a new context. ! 230: ! 231: digestAlgorithm is the algorithm with which data are digested, and ! 232: must be one of the values listed in Appendix D. ! 233: ! 234: Return value: 0 success ! 235: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 236: ! 237: ! 238: R_SignUpdate ! 239: ! 240: int R_SignUpdate ( ! 241: R_SIGNATURE_CTX *context, /* context */ ! 242: unsigned char *partIn, /* next data part */ ! 243: unsigned char partInLen /* length of next data part */ ! 244: ); ! 245: ! 246: R_SignUpdate continues a signature operation, digesting partIn, the ! 247: next data part, with the specified message-digest algorithm. It may ! 248: be called any number of times. ! 249: ! 250: Return value: 0 success ! 251: ! 252: ! 253: R_SignFinal ! 254: ! 255: int R_SignFinal ( ! 256: R_SIGNATURE_CTX *context, /* context */ ! 257: unsigned char *signature, /* signature */ ! 258: unsigned int *signatureLen, /* length of signature */ ! 259: R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ ! 260: ); ! 261: ! 262: R_SignFinal completes a signature operation, encrypting the message ! 263: digest with the signer's private key. It stores the resulting ! 264: signature in signature and its length in signatureLen. ! 265: ! 266: signatureLen will not be greater than MAX_SIGNATURE_LEN. ! 267: ! 268: Return value: 0 success ! 269: RE_PRIVATE_KEY privateKey cannot encrypt message digest ! 270: ! 271: ! 272: 3.2 Verifying a signature ! 273: ! 274: RSAREF verifies signatures with three procedures: R_VerifyInit, ! 275: R_VerifyUpdate, and R_VerifyFinal. These procedures are typically ! 276: called by message-processing applications and by certification ! 277: applications when processing a certification request. ! 278: ! 279: An application first calls R_VerifyInit, giving an integer specifying ! 280: which message-digest algorithm to apply (see Appendix D). ! 281: R_VerifyInit sets up a context for the verification operation, and ! 282: returns the context. ! 283: ! 284: The application then calls R_VerifyUpdate any number of times, giving ! 285: the context and the next data part. R_VerifyUpdate digests the part. ! 286: ! 287: After all the parts are supplied, the application calls ! 288: R_VerifyFinal, giving the context, the signer's RSA public key, and ! 289: the signature. R_SignFinal decrypts the signature with the public key ! 290: and compares the result to the message digest to see whether the ! 291: signature is valid. ! 292: ! 293: An application may call R_VerifyUpdate again after R_VerifyFinal to ! 294: verify other signatures, without setting up a new context. ! 295: ! 296: ! 297: R_VerifyInit ! 298: ! 299: int R_VerifyInit ( ! 300: R_SIGNATURE_CTX *context, /* new context */ ! 301: int digestAlgorithm /* message-digest algorithm */ ! 302: ); ! 303: ! 304: R_VerifyInit begins a verification operation, setting up a new ! 305: context. ! 306: ! 307: digestAlgorithm is the algorithm with which data are digested, and ! 308: must be one of the values listed in Appendix D. ! 309: ! 310: Return value: 0 success ! 311: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 312: ! 313: ! 314: R_VerifyUpdate ! 315: ! 316: int R_VerifyUpdate ( ! 317: R_SIGNATURE_CTX *context, /* context */ ! 318: unsigned char *partIn, /* next data part */ ! 319: unsigned int partInLen /* length of next data part */ ! 320: ); ! 321: ! 322: R_VerifyUpdate continues a verification operation, digesting partIn, ! 323: the next data part, with the specified message-digest algorithm. It ! 324: may be called any number of times. ! 325: ! 326: Return value: 0 success ! 327: ! 328: ! 329: R_VerifyFinal ! 330: ! 331: int R_VerifyFinal ( ! 332: R_SIGNATURE_CTX *context, /* context */ ! 333: unsigned char *signature, /* signature */ ! 334: unsigned int signatureLen, /* length of signature */ ! 335: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 336: ); ! 337: ! 338: R_VerifyFinal completes a verification operation, decrypting the ! 339: signature with the signer's public key and comparing it to the ! 340: message digest. ! 341: ! 342: signatureLen must not be greater than MAX_SIGNATURE_LEN. ! 343: ! 344: Return value: 0 success ! 345: RE_LEN signatureLen out of range ! 346: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 347: RE_SIGNATURE signature is incorrect ! 348: ! 349: ! 350: 3.3 Sealing data in a digital envelope ! 351: ! 352: RSAREF seals data in digital envelopes with three procedures: ! 353: R_SealInit, R_SealUpdate, and R_SealFinal. There may be any number of ! 354: recipients. These procedures are typically called by ! 355: message-processing applications. ! 356: ! 357: An application first calls R_SealInit, giving an integer specifying ! 358: which data encryption algorithm to apply (see Appendix D), the public ! 359: key of each recipient, and a random structure. R_SealInit sets up a ! 360: context for the sealing operation, generates a data encryption key ! 361: and an initialization vector, and encrypts the data encryption key ! 362: with each recipient's public key. It returns the context, the ! 363: initialization vector, and the encrypted data encryption keys. ! 364: ! 365: The application then calls R_SealUpdate any number of times, giving ! 366: the context and the next data part. R_SealUpdate encrypts the part ! 367: and returns the next encrypted data part. (Depending on how data are ! 368: supplied, it may return more or less data than are supplied.) ! 369: ! 370: After all the parts are supplied, the application calls R_SealFinal, ! 371: giving the context. R_SealFinal returns the last encrypted data part. ! 372: ! 373: An application may call R_SealUpdate again after R_SealFinal to ! 374: encrypt other data under the same data encryption key and ! 375: initialization vector. This is useful when message content is signed ! 376: and encrypted, and the digital signature must also be encrypted. ! 377: ! 378: ! 379: R_SealInit ! 380: ! 381: int R_SealInit ( ! 382: R_ENVELOPE_CTX *context, /* new context */ ! 383: unsigned char **encryptedKeys, /* encrypted keys */ ! 384: unsigned int *encryptedKeyLens, /* lengths of encrypted keys */ ! 385: unsigned char iv[8], /* initialization vector */ ! 386: unsigned int publicKeyCount, /* number of public keys */ ! 387: R_RSA_PUBLIC_KEY **publicKeys, /* public keys */ ! 388: int encryptionAlgorithm, /* data encryption algorithm */ ! 389: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 390: ); ! 391: ! 392: R_SealInit begins a "sealing" operation. It performs the following ! 393: steps: ! 394: ! 395: 1. It sets up a new context. ! 396: ! 397: 2. It generates a random data encryption key and initialization ! 398: vector, storing the initialization vector in iv. ! 399: ! 400: 3. It encrypts the data encryption key with each recipient's ! 401: public key, storing the encrypted keys in encryptedKeys and ! 402: their lengths in encryptedKeyLens. (Note that each ! 403: encryptedKeys member should be a pointer, initialized by ! 404: the application.) ! 405: ! 406: The encryptedKeyLens members will not be greater than ! 407: MAX_ENCRYPTED_KEY_LEN. ! 408: ! 409: encryptionAlgorithm is the algorithm with which data are encrypted, ! 410: and must be one of the values listed in Appendix D. ! 411: ! 412: randomStruct must have been seeded. ! 413: ! 414: Return value: 0 success ! 415: RE_ENCRYPTION_ALGORITHM encryptionAlgorithm is invalid ! 416: RE_PUBLIC_KEY publicKey cannot encrypt data encryption ! 417: key ! 418: RE_NEED_RANDOM randomStruct is not seeded ! 419: ! 420: ! 421: R_SealUpdate ! 422: ! 423: int R_SealUpdate ( ! 424: R_ENVELOPE_CTX *context, /* context */ ! 425: unsigned char *partOut, /* next encrypted data part */ ! 426: unsigned int *partOutLen, /* length of next encrypted data part */ ! 427: unsigned char *partIn, /* next data part */ ! 428: unsigned int partInLen /* length of next data part */ ! 429: ); ! 430: ! 431: R_SealUpdate continues a sealing operation, decrypting partIn, the ! 432: next data part, with the specified data encryption algorithm, and ! 433: returning partOut, the next encrypted data part. It may be called any ! 434: number of times. ! 435: ! 436: partOutLen will always be a multiple of 8, and it will not be greater ! 437: than partInLen+7. If partInLen is a multiple of 8, then partOutLen ! 438: will be the same as partInLen. ! 439: ! 440: (As a special case, if partInLen is a multiple of 24, then partOutLen ! 441: will be the same as partInLen; this is helpful when the output is to ! 442: be encoded in ASCII, since the length of each part input to ! 443: R_EncodePEMBlock should be a multiple of 3.) ! 444: ! 445: Return value: 0 success ! 446: ! 447: ! 448: R_SealFinal ! 449: ! 450: int R_SealFinal ( ! 451: R_ENVELOPE_CTX *context, /* context */ ! 452: unsigned char *partOut, /* last encrypted data part */ ! 453: unsigned int *partOutLen /* length of last encrypted data part */ ! 454: ); ! 455: ! 456: R_SealFinal completes a sealing operation, returning partOut, the ! 457: last encrypted data part. ! 458: ! 459: partOutLen will always be 8. ! 460: ! 461: Return value: 0 success ! 462: ! 463: ! 464: 3.4 Opening a digital envelope ! 465: ! 466: RSAREF opens digital envelopes with three procedures: R_OpenInit, ! 467: R_OpenUpdate, and R_OpenFinal. These procedures are typically called ! 468: by message-processing applications. ! 469: ! 470: An application first calls R_OpenInit, giving an integer specifying ! 471: which data encryption algorithm to apply (see Appendix D), an ! 472: initialization vector, the recipient's RSA private key, and an ! 473: encrypted data encryption key. R_OpenInit sets up a context for the ! 474: opening operation and decrypts the encrypted data encryption key with ! 475: the private key. It returns the context. ! 476: ! 477: The application then calls R_OpenUpdate any number of times, giving ! 478: the context and the next encrypted data part. R_OpenUpdate decrypts ! 479: the encrypted part and returns the next recovered data part. (Depending ! 480: on how data are supplied, it may return more or less data than are ! 481: supplied.) ! 482: ! 483: After all the parts are supplied, the application calls R_OpenFinal, ! 484: giving the context. R_OpenFinal returns the last recovered data part. ! 485: ! 486: As described for the sealing operations, an application may call ! 487: R_OpenUpdate again after R_OpenFinal to decrypt other data under the ! 488: same data encryption key and initialization vector. ! 489: ! 490: ! 491: R_OpenInit ! 492: ! 493: int R_OpenInit ( ! 494: R_ENVELOPE_CTX *context, /* new context */ ! 495: int encryptionAlgorithm, /* data encryption algorithm */ ! 496: unsigned char *encryptedKey, /* encrypted data encryption key */ ! 497: unsigned int encryptedKeyLen, /* length of encrypted key */ ! 498: unsigned char iv[8], /* initialization vector */ ! 499: R_RSA_PRIVATE_KEY *privateKey /* recipient's RSA private key */ ! 500: ); ! 501: ! 502: R_OpenInit begins an "opening" operation, setting up a new context ! 503: and decrypting encryptedKey with privateKey. ! 504: ! 505: iv is the initialization vector for the data encryption algorithm. ! 506: encryptionAlgorithm is the algorithm with which the data is ! 507: encrypted, and must be one of the values listed in Appendix D. ! 508: ! 509: encryptedKeyLen must not be greater than MAX_ENCRYPTED_KEY_LEN. ! 510: ! 511: Return value: 0 success ! 512: RE_LEN encryptedKeyLen out of range ! 513: RE_ENCRYPTION_ALGORITHM encryptionAlgorithm is invalid ! 514: RE_PRIVATE_KEY privateKey cannot decrypt encrypted key ! 515: ! 516: ! 517: R_OpenUpdate ! 518: ! 519: int R_OpenUpdate ( ! 520: R_ENVELOPE_CTX *context, /* context */ ! 521: unsigned char *partOut, /* next recovered data part */ ! 522: unsigned int *partOutLen, /* length of next recovered data part */ ! 523: unsigned char *partIn, /* next encrypted data part */ ! 524: unsigned int partInLen /* length of next encrypted data part */ ! 525: ); ! 526: ! 527: R_OpenUpdate continues an opening operation, decrypting partIn, the ! 528: next encrypted data part, and returning partOut, the next recovered ! 529: data part. It may be called any number of times. ! 530: ! 531: partOutLen will always be a multiple of 8, and it will not be greater ! 532: than partInLen+7. ! 533: ! 534: Return value: 0 success ! 535: ! 536: ! 537: R_OpenFinal ! 538: ! 539: int R_OpenFinal ( ! 540: R_ENVELOPE_CTX *context, /* context */ ! 541: unsigned char *partOut, /* last recovered data part */ ! 542: unsigned int *partOutLen /* length of last recovered data part */ ! 543: ); ! 544: ! 545: R_SealFinal completes a sealing operation, returning partOut, the ! 546: last recovered data part. ! 547: ! 548: partOutLen will not be greater than 7. ! 549: ! 550: Return value: 0 success ! 551: RE_KEY recovered data encryption key cannot decrypt ! 552: encrypted data ! 553: ! 554: 3.5 Digesting a message ! 555: ! 556: RSAREF digests messages with three procedures: R_DigestInit, ! 557: R_DigestUpdate, and R_DigestFinal. These procedures have no ! 558: particular PEM application, but may be useful in PKCS #7. ! 559: ! 560: An application first calls R_DigestInit, giving an integer specifying ! 561: which message-digest algorithm to apply (see Appendix D). ! 562: R_DigestInit sets up a context for the digesting operation, and ! 563: returns the context. ! 564: ! 565: The application then calls R_DigestUpdate any number of times, giving ! 566: the context and the next data part. R_DigestUpdate digests the part. ! 567: ! 568: After all the parts are supplied, the application calls ! 569: R_DigestFinal, giving the context. R_DigestFinal returns the message ! 570: digest. ! 571: ! 572: An application may call R_DigestUpdate again after R_DigestFinal to ! 573: digest other data, without setting up a new context. ! 574: ! 575: ! 576: R_DigestInit ! 577: ! 578: int R_DigestInit ( ! 579: R_DIGEST_CTX *context, /* new context */ ! 580: int digestAlgorithm /* message-digest algorithm */ ! 581: ); ! 582: ! 583: R_DigestInit begins a message-digest operation, setting up a new ! 584: context. ! 585: ! 586: digestAlgorithm is the algorithm with which data are digested, and ! 587: must be one of the values listed in Appendix D. ! 588: ! 589: Return value: 0 success ! 590: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 591: ! 592: ! 593: R_DigestUpdate ! 594: ! 595: int R_DigestUpdate ( ! 596: R_DIGEST_CTX *context, /* context */ ! 597: unsigned char *partIn, /* next data part */ ! 598: unsigned int partInLen /* length of next data part */ ! 599: ); ! 600: ! 601: R_DigestUpdate continues a message-digest operation, digesting the ! 602: next data part with the specified message-digest algorithm. It may be ! 603: called any number of times. ! 604: ! 605: Return value: 0 success ! 606: ! 607: ! 608: R_DigestFinal ! 609: ! 610: int R_DigestFinal ( ! 611: R_DIGEST_CTX *context, /* context */ ! 612: unsigned char *digest, /* message digest */ ! 613: unsigned int *digestLen /* length of message digest */ ! 614: ); ! 615: ! 616: R_DigestFinal completes a message-digest operation, storing the ! 617: message digest in digest and its length in bytes in digestLen. ! 618: ! 619: digestLen will not be greater than MAX_DIGEST_LEN. ! 620: ! 621: Return value: 0 success ! 622: ! 623: ! 624: 4. ENCODING AND DECODING ! 625: ! 626: RSAREF encodes and decodes blocks of data in printable ASCII ! 627: according to RFC 1421 with two procedures: R_EncodePEMBlock ! 628: and R_DecodePEMBlock. They are typically called by ! 629: message-processing applications to format and parse fields ! 630: of the encapsulated header of a privacy-enhanced message, as ! 631: well as the message content. ! 632: ! 633: To encode a block in printable ASCII, an application calls ! 634: R_EncodePEMBlock, giving a pointer to the block and the block length. ! 635: R_EncodePEMBlock encodes the block in printable ASCII and returns the ! 636: encoded block. ! 637: ! 638: To decode a block encoded in printable ASCII, an application calls ! 639: R_DecodePEMBlock, giving a pointer to the encoded block, and the ! 640: encoded block length. R_DecodePEMBlock decodes the encoded block and ! 641: returns the decoded block. ! 642: ! 643: An application can process data in parts with these procedures, ! 644: provided that the length of each input part (except possibly the ! 645: last) is a multiple of the "quantum" size: three bytes for ! 646: encoding, four bytes for decoding. ! 647: ! 648: ! 649: R_EncodePEMBlock ! 650: ! 651: int R_EncodePEMBlock ( ! 652: unsigned char *encodedBlock, /* encoded block */ ! 653: unsigned int *encodedBlockLen, /* length of encoded block */ ! 654: unsigned char *block, /* block */ ! 655: unsigned int blockLen /* length of block */ ! 656: ); ! 657: ! 658: R_EncodePEMBlock encodes block in printable ASCII according to RFC ! 659: 1421, storing the encoding in encodedBlock. ! 660: ! 661: encodedBlock will be an ASCII string, encoded according to RFC 1421. ! 662: (It will not contain any line delimiters; the application must break ! 663: the string into lines.) encodedBlockLen will not be greater than ! 664: ENCODED_CONTENT_LEN(blockLen). ! 665: ! 666: When processing data in parts, blockLen should be a multiple of 3, ! 667: except possibly for the last part. ! 668: ! 669: Return value: 0 success ! 670: nonzero reserved for future compatibility ! 671: ! 672: ! 673: R_DecodePEMBlock ! 674: ! 675: int R_DecodePEMBlock (block, blockLen, encodedBlock, encodedBlockLen) ! 676: unsigned char *block, /* block */ ! 677: unsigned int *blockLen, /* length of block */ ! 678: unsigned char *encodedBlock, /* encoded block */ ! 679: unsigned int encodedBlockLen /* length of encoded block */ ! 680: ); ! 681: ! 682: R_DecodePEMBlock decodes a block encoded according to RFC 1421. Its ! 683: operation is the reverse of R_EncodePEMBlock. ! 684: ! 685: blockLen will not be greater than ! 686: DECODED_CONTENT_LEN(encodedBlockLen). ! 687: ! 688: When processing data in parts, encodedBlockLen should be a multiple ! 689: of 4, except possibly for the last part. ! 690: ! 691: Return value: 0 success ! 692: RE_ENCODING encodedBlock has RFC 1421 encoding error ! 693: ! 694: ! 695: 5. KEY-PAIR GENERATION ! 696: ! 697: RSAREF generates key pairs with the procedure R_GeneratePEMKeys. ! 698: R_GeneratePEMKeys is typically called by key generation applications. ! 699: To generate a new key pair, an application calls R_GeneratePEMKeys, ! 700: giving the length in bits of the modulus, the choice of public ! 701: exponent (3 or 65537), and a random structure. R_GeneratePEMKeys ! 702: generates an RSA key pair and returns the public and private keys. ! 703: ! 704: ! 705: R_GeneratePEMKeys ! 706: ! 707: int R_GeneratePEMKeys ( ! 708: R_RSA_PUBLIC_KEY *publicKey, /* new RSA public key */ ! 709: R_RSA_PRIVATE_KEY *privateKey, /* new RSA private key */ ! 710: R_RSA_PROTO_KEY *protoKey, /* RSA prototype key */ ! 711: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 712: ); ! 713: ! 714: R_GeneratePEMKeys generates a random RSA key pair, storing the ! 715: resulting RSA public key in publicKey and the resulting RSA private ! 716: key in privateKey. ! 717: ! 718: Other parameters are as follows: ! 719: ! 720: protoKey The RSA prototype key specifying the length ! 721: in bits of the RSA modulus and the public ! 722: exponent. (See Appendix B.) ! 723: ! 724: randomStruct Random structure from which the key pair is ! 725: derived. It must have been seeded. ! 726: ! 727: Return value: 0 success ! 728: RE_MODULUS_LEN modulus length invalid ! 729: RE_NEED_RANDOM randomStruct is not seeded ! 730: ! 731: ! 732: 6. DIFFIE-HELLMAN KEY AGREEMENT ! 733: ! 734: To generate new Diffie-Hellman parameters, an application calls ! 735: R_GenerateDHParams, giving the length in bits of the Diffie-Hellman ! 736: prime and a random structure. R_GenerateDHParams generates the ! 737: parameters. Several users may share given Diffie-Hellman parameters, ! 738: or they may be unique to a given user. ! 739: ! 740: To set up a key agreement, communicating applications call ! 741: R_SetupDHAgreement, giving these parameters: ! 742: ! 743: - the Diffie-Hellman parameters ! 744: - a random structure ! 745: ! 746: R_SetupDHAgreement generates a new "public value" and a new "private ! 747: value" for each party. The applications then exchange their public ! 748: values. ! 749: ! 750: To compute the agreed-upon key, the applications call ! 751: R_ComputeDHAgreedKey, giving these parameters: ! 752: ! 753: - the Diffie-Hellman parameters ! 754: - the other party's public value ! 755: - the private value ! 756: ! 757: R_ComputeDHAgreedKey computes the agreed-upon key. ! 758: ! 759: The applications may encrypt subsequent data with the agreed-upon ! 760: key. When the length of the Diffie-Hellman prime is large enough, it ! 761: is considered impractical for someone who sees the Diffie-Hellman ! 762: parameters and the exchanged public values to determine to ! 763: agreed-upon key, so the subsequent encryption is secure. ! 764: ! 765: ! 766: R_GenerateDHParams ! 767: ! 768: int R_GenerateDHParams ( ! 769: R_DH_PARAMS *params, /* new Diffie-Hellman parameters */ ! 770: unsigned int primeBits, /* length in bits of prime */ ! 771: unsigned int subPrimeBits, /* length in bits of subprime */ ! 772: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 773: ); ! 774: ! 775: R_GenerateDHParams generates random Diffie-Hellman parameters, ! 776: storing the result in params. primeBits specifies the length in bits ! 777: of the Diffie-Hellman prime p, and subPrimeBits specifies the length ! 778: in bits of the prime q that divides p-1. The resulting generator g ! 779: has order q. ! 780: ! 781: The resulting params->primeLen and params->generatorLen will be at ! 782: most DH_PRIME_LEN (bits); params->prime and params->generator should ! 783: point to arrays at least that long. ! 784: ! 785: randomStruct must have been seeded. ! 786: ! 787: Return value: 0 success ! 788: RE_MODULUS_LEN prime length invalid ! 789: RE_NEED_RANDOM randomStruct is not seeded ! 790: ! 791: ! 792: R_SetupDHAgreement ! 793: ! 794: int R_SetupDHAgreement ( ! 795: unsigned char *publicValue, /* new public value */ ! 796: unsigned char *privateValue, /* new private value */ ! 797: unsigned int privateValueLen, /* length of private value */ ! 798: R_DH_PARAMS *params, /* Diffie-Hellman parameters */ ! 799: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 800: ); ! 801: ! 802: R_SetupDHAgreement sets up a Diffie-Hellman key agreement by ! 803: generating a public value and a private value from the Diffie-Hellman ! 804: parameters. It stores the resulting public value in publicValue and ! 805: the resulting private value in private value. ! 806: ! 807: The private value is a random number x whose length in bytes is ! 808: privateValueLen, and the public value is the number y such that ! 809: ! 810: y = g^x mod p, ! 811: ! 812: where p and g are the prime and generator in params. (Typically, one ! 813: selects privateValueLen according to the length in bits of the ! 814: "subprime" q.) ! 815: ! 816: publicValue and privateValue will be represented most significant ! 817: byte first, with no leading zero bytes. publicValue will have the ! 818: same length as the prime. ! 819: ! 820: randomStruct must have been seeded. ! 821: ! 822: Return value: 0 success ! 823: RE_NEED_RANDOM randomStruct is not seeded ! 824: ! 825: ! 826: R_ComputeDHAgreedKey ! 827: ! 828: int R_ComputeDHAgreedKey ( ! 829: unsigned char *agreedKey, /* new agreed-upon key */ ! 830: unsigned char *otherPublicValue, /* other's public value */ ! 831: unsigned char *privateValue, /* private value */ ! 832: unsigned int privateValueLen, /* length of private value */ ! 833: R_DH_PARAMS *params /* Diffie-Hellman parameters */ ! 834: ); ! 835: ! 836: R_ComputeDHAgreedKey computes an agreed-upon key from the other ! 837: party's public value, a private value, and the Diffie-Hellman ! 838: parameters. It stores the resulting agreed key in agreedKey. ! 839: ! 840: The agreed key is the number z such that ! 841: ! 842: z = (y')^x mod p, ! 843: ! 844: where y' is the other party's public value, x is the private value, ! 845: and p is the prime in params. ! 846: ! 847: The other party's private value y' should be between 0 and p-1. ! 848: ! 849: agreedKey will be represented most significant byte first, with no ! 850: leading zero bytes. agreedKey will have the same length as the prime. ! 851: ! 852: Return value: 0 success ! 853: RE_DATA other party's private value out of range ! 854: ! 855: ! 856: 7. VERSION 1.0 ROUTINES ! 857: ! 858: The following procedures are retained for backward compatibility with ! 859: RSAREF 1.0: R_SignPEMBlock, R_SignBlock, R_VerifyPEMSignature, ! 860: R_VerifyBlockSignature, R_SealPEMBlock, R_OpenPEMBlock, and ! 861: R_DigestBlock. ! 862: ! 863: The procedures are typically called by message-processing ! 864: applications. R_SignBlock is also typically called by key-generation ! 865: applications when constructing a PEM or PKCS certification request, ! 866: and by certification applications when signing a certificate. ! 867: R_DigestBlock has no particular PEM application, but may be useful in ! 868: PKCS #7. ! 869: ! 870: To sign a message, an application calls R_SignPEMBlock, giving these ! 871: arguments: ! 872: ! 873: - a pointer to the message content, and the message length ! 874: - an integer identifying which message-digest algorithm to apply ! 875: (see Appendix D) ! 876: - a flag indicating whether to encode the message in printable ! 877: ASCII according to RFC 1421 ! 878: - the signer's RSA private key ! 879: ! 880: R_SignPEMBlock signs the message with the signer's private key and ! 881: the specified message-digest algorithm, and optionally encodes the ! 882: message in printable ASCII. It returns the signature and possibly the ! 883: encoded message. The signature is encoded according to RFC 1421. ! 884: ! 885: To sign a block of data such as a certificate where the signature is ! 886: not encoded in printable ASCII, an application calls R_SignBlock, ! 887: giving these arguments: ! 888: ! 889: - a pointer to the block, and the block length ! 890: - an integer identifying which message-digest algorithm to apply ! 891: (see Appendix D) ! 892: - the signer's RSA private key ! 893: ! 894: R_SignBlock signs the message with the signer's private key and the ! 895: specified message-digest algorithm. It returns the signature. ! 896: ! 897: To verify a signature on a message, an application calls ! 898: R_VerifyPEMSignature, giving these arguments: ! 899: ! 900: - a pointer to the (possibly encoded) message, and the message ! 901: length ! 902: - a pointer to the signature, and the signature length ! 903: - an integer identifying which message-digest algorithm was applied ! 904: (see Appendix D) ! 905: - a flag indicating whether the message was encoded in printable ! 906: ASCII ! 907: - the signer's RSA public key ! 908: ! 909: R_VerifyPEMSignature decodes the message if it was encoded and ! 910: verifies the signature on the message with the signer's public key ! 911: and the specified message-digest algorithm. It returns the message ! 912: content if the message was encoded. ! 913: ! 914: To verify a signature on a block of data such as a certificate where ! 915: the signature is not encoded in printable ASCII, an application calls ! 916: R_VerifyBlockSignature, giving these arguments: ! 917: ! 918: - a pointer to the block, and the block length ! 919: - a pointer to the signature, and the signature length ! 920: - an integer identifying which message-digest algorithm was applied ! 921: (see Appendix D) ! 922: - the signer's RSA public key ! 923: ! 924: R_VerifyBlockSignature verifies the signature on the message with the ! 925: signer's public key and the specified message-digest algorithm. ! 926: ! 927: To sign and encrypt a message, an application calls R_SealPEMBlock, ! 928: giving these arguments: ! 929: ! 930: - a pointer to the message content, and the message length ! 931: - an integer identifying which message-digest algorithm to apply ! 932: (see Appendix D) ! 933: - the signer's RSA private key ! 934: - the recipient's RSA public key ! 935: - a random structure ! 936: ! 937: R_SealPEMBlock signs the message with the signer's private key and ! 938: the specified message-digest algorithm, encrypts the message and the ! 939: signature with a random DES key, and encrypts the DES key with the ! 940: recipient's public key. It returns the encrypted message, the ! 941: encrypted key, the encrypted signature, and the DES initialization ! 942: vector. The encrypted message, key, and signature are encoded ! 943: according to RFC 1421. ! 944: ! 945: To open a message (decrypt it and verify its signature), an ! 946: application calls R_OpenPEMBlock, giving these arguments: ! 947: ! 948: - a pointer to the encrypted message, and the encrypted message ! 949: length ! 950: - a pointer to the encrypted key, and the encrypted key length ! 951: - a pointer to the encrypted signature, and the encrypted signature ! 952: length ! 953: - a DES initialization vector ! 954: - an integer identifying which message-digest algorithm was applied ! 955: (see Appendix D) ! 956: - the signer's RSA public key ! 957: - the recipient's RSA private key ! 958: ! 959: R_OpenPEMBlock decrypts the encrypted DES key with the recipient's ! 960: private key, decrypts the encrypted message and the encrypted ! 961: signature with the DES key, and verifies the signature on the message ! 962: with the signer's public key and the specified message-digest ! 963: algorithm. It returns the message content. ! 964: ! 965: To digest a block of data such as a prototype certificate, an ! 966: application calls R_DigestBlock, giving these arguments: ! 967: ! 968: - a pointer to the block, and the block length ! 969: - an integer identifying which message-digest algorithm to apply ! 970: (see Appendix D) ! 971: ! 972: R_DigestBlock digests the block with the specified message-digest ! 973: algorithm. It returns the message digest. ! 974: ! 975: ENCODED_CONTENT_LEN, DECODED_CONTENT_LEN, ENCRYPTED_CONTENT_LEN, and ! 976: DECRYPTED_CONTENT_LEN are macros that assist in determining the ! 977: maximum lengths of the results of cryptographic enhancements. ! 978: ! 979: ! 980: R_SignPEMBlock ! 981: ! 982: int R_SignPEMBlock ( ! 983: unsigned char *encodedContent, /* encoded content */ ! 984: unsigned int *encodedContentLen, /* length of encoded content */ ! 985: unsigned char *encodedSignature, /* encoded signature */ ! 986: unsigned int *encodedSignatureLen, /* length of encoded signature */ ! 987: unsigned char *content, /* content */ ! 988: unsigned int contentLen, /* length of content */ ! 989: int recode, /* recoding flag */ ! 990: int digestAlgorithm, /* message-digest algorithm */ ! 991: R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ ! 992: ); ! 993: ! 994: R_SignPEMBlock computes a digital signature on content. Specifically, ! 995: R_SignPEMBlock performs the following steps: ! 996: ! 997: 1. It digests content with digestAlgorithm, giving a message ! 998: digest. ! 999: ! 1000: 2. It encrypts the message digest with privateKey, giving a ! 1001: digital signature, and encodes the result in printable ! 1002: ASCII according to RFC 1421, storing the encoding in ! 1003: encodedSignature. ! 1004: ! 1005: 3. If recode is nonzero, it encodes content in printable ASCII, ! 1006: storing the encoding in encodedContent. ! 1007: ! 1008: If recode is nonzero, encodedContent will be an ASCII string, encoded ! 1009: according to RFC 1421. (It will not contain any line delimiters; the ! 1010: application must break the string into 64-character lines.) ! 1011: encodedContentLen will not be greater than ! 1012: ENCODED_CONTENT_LEN(contentLen). If recode is zero, encodedContent is ! 1013: ignored. ! 1014: ! 1015: encodedSignature will be an ASCII string, encoded according to RFC ! 1016: 1421. encodedSignatureLen will not be greater than ! 1017: MAX_PEM_SIGNATURE_LEN. ! 1018: ! 1019: digestAlgorithm is the algorithm with which the message content is ! 1020: digested, and must be one of the values listed in Appendix D. ! 1021: ! 1022: Return value: 0 success ! 1023: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1024: RE_PRIVATE_KEY privateKey cannot encrypt message digest ! 1025: ! 1026: ! 1027: R_SignBlock ! 1028: ! 1029: int R_SignBlock ( ! 1030: unsigned char *signature, /* encoded signature */ ! 1031: unsigned int *signatureLen, /* length of encoded signature */ ! 1032: unsigned char *block, /* block */ ! 1033: unsigned int blockLen, /* length of block */ ! 1034: int digestAlgorithm, /* message-digest algorithm */ ! 1035: R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ ! 1036: ); ! 1037: ! 1038: R_SignBlock computes a digital signature on block of data such as a ! 1039: certificate. Its operation is similar to R_SignPEMBlock, except that ! 1040: the resulting signature is an arbitrary byte string, rather than an ! 1041: RFC 1421-encoded string. ! 1042: ! 1043: signatureLen will not be greater than MAX_SIGNATURE_LEN. ! 1044: ! 1045: Return value: 0 success ! 1046: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1047: RE_PRIVATE_KEY privateKey cannot encrypt message digest ! 1048: ! 1049: ! 1050: R_VerifyPEMSignature ! 1051: ! 1052: int R_VerifyPEMSignature ( ! 1053: unsigned char *content, /* content */ ! 1054: unsigned int *contentLen, /* length of content */ ! 1055: unsigned char *encodedContent, /* (possibly) encoded content */ ! 1056: unsigned int encodedContentLen, /* length of encoded content */ ! 1057: unsigned char *encodedSignature, /* encoded signature */ ! 1058: unsigned int encodedSignatureLen, /* length of encoded signature */ ! 1059: int recode, /* recoding flag */ ! 1060: int digestAlgorithm, /* message-digest algorithm */ ! 1061: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 1062: ); ! 1063: ! 1064: R_VerifyPEMSignature verifies a digital signature on a message. Its ! 1065: operation is the inverse of R_SignPEMBlock. R_VerifyPEMSignature ! 1066: operates on encodedSignature and encodedContent. If recode is ! 1067: nonzero, it first decodes encodedContent according to RFC 1421, and ! 1068: stores the result in content. If recode is zero, content is ignored. ! 1069: ! 1070: If recode is nonzero, contentLen will not be greater than ! 1071: DECODED_CONTENT_LEN(encodedContentLen). ! 1072: ! 1073: Return value: 0 success ! 1074: RE_CONTENT_ENCODING encodedContent has RFC 1421 encoding error ! 1075: RE_SIGNATURE_ENCODING encodedSignature has RFC 1421 encoding error ! 1076: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1077: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 1078: RE_SIGNATURE signature on content is incorrect ! 1079: ! 1080: ! 1081: R_VerifyBlockSignature ! 1082: ! 1083: int R_VerifyBlockSignature ( ! 1084: unsigned char *block, /* block */ ! 1085: unsigned int blockLen, /* length of block */ ! 1086: unsigned char *signature, /* signature */ ! 1087: unsigned int signatureLen, /* length of signature */ ! 1088: int digestAlgorithm, /* message-digest algorithm */ ! 1089: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 1090: ); ! 1091: ! 1092: R_VerifyBlockSignature verifies a digital signature on a block of ! 1093: data such as a certificate. Its operation is similar to ! 1094: R_VerifyPEMSignature, except that the block and signature are ! 1095: arbitrary byte strings, rather than RFC 1421-encoded strings. ! 1096: ! 1097: Return value: 0 success ! 1098: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1099: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 1100: RE_SIGNATURE signature on block is incorrect ! 1101: ! 1102: ! 1103: R_SealPEMBlock ! 1104: ! 1105: int R_SealPEMBlock ( ! 1106: unsigned char *encryptedContent, /* encoded, encrypted content */ ! 1107: unsigned int *encryptedContentLen, ! 1108: /* length of encoded, encrypted content */ ! 1109: unsigned char *encryptedKey, /* encoded, encrypted DES key */ ! 1110: unsigned int *encryptedKeyLen, ! 1111: /* length of encoded, encrypted DES key */ ! 1112: unsigned char *encryptedSignature,/* encoded, encrypted signature */ ! 1113: unsigned int *encryptedSignatureLen, ! 1114: /* length of encoded, encrypted signature */ ! 1115: unsigned char iv[8], /* DES initialization vector */ ! 1116: unsigned char *content, /* content */ ! 1117: unsigned int contentLen, /* length of content */ ! 1118: int digestAlgorithm, /* message-digest algorithm */ ! 1119: R_RSA_PUBLIC_KEY *publicKey, /* recipient's RSA public key */ ! 1120: R_RSA_PRIVATE_KEY *privateKey, /* signer's RSA private key */ ! 1121: R_RANDOM_STRUCT *randomStruct /* random structure */ ! 1122: ); ! 1123: ! 1124: R_SealPEMBlock computes a digital signature on content then encrypts ! 1125: the content and the signature. Specifically, R_SealPEMBlock performs ! 1126: the following steps: ! 1127: ! 1128: 1. It digests content with digestAlgorithm, giving a message ! 1129: digest. ! 1130: ! 1131: 2. It encrypts the message digest with privateKey, giving a ! 1132: digital signature. ! 1133: ! 1134: 3. It generates a random DES key and initialization vector, ! 1135: storing the initialization vector in iv. ! 1136: ! 1137: 4. It encrypts content with the DES key and initialization vector ! 1138: in cipher-block chaining mode, and encodes the result in ! 1139: printable ASCII according to RFC 1421, storing the encoding ! 1140: in encryptedContent. ! 1141: ! 1142: 5. It encrypts the DES key with publicKey and encodes the ! 1143: result in printable ASCII, storing the encoding in ! 1144: encryptedKey. ! 1145: ! 1146: 6. It encrypts the digital signature with the DES key and ! 1147: initialization vector, and encodes the result in printable ! 1148: ASCII, storing the encoding in encryptedSignature. ! 1149: ! 1150: encryptedContent will be an ASCII string, encoded according to RFC ! 1151: 1421. (It will not contain any line delimiters; the application must ! 1152: break the string into 64-character lines.) encryptedContentLen will ! 1153: not be greater than ENCRYPTED_CONTENT_LEN(contentLen). ! 1154: ! 1155: encryptedKey and encryptedSignature will be ASCII strings, encoded ! 1156: according to RFC 1421. encryptedKeyLen will not be greater than ! 1157: MAX_PEM_ENCRYPTED_KEY_LEN. encryptedSignatureLen will not be greater ! 1158: than MAX_PEM_ENCRYPTED_SIGNATURE_LEN. ! 1159: ! 1160: digestAlgorithm is the algorithm with which the message content is ! 1161: digested, and must be one of the values listed in Appendix D. ! 1162: ! 1163: randomStruct must have been seeded. ! 1164: ! 1165: Return value: 0 success ! 1166: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1167: RE_PRIVATE_KEY privateKey cannot encrypt message digest ! 1168: RE_PUBLIC_KEY publicKey cannot encrypt DES key ! 1169: RE_NEED_RANDOM randomStruct is not seeded ! 1170: ! 1171: ! 1172: R_OpenPEMBlock ! 1173: ! 1174: int R_OpenPEMBlock ( ! 1175: unsigned char *content, /* content */ ! 1176: unsigned int *contentLen, /* length of content */ ! 1177: unsigned char *encryptedContent, /* encoded, encrypted content */ ! 1178: unsigned int encryptedContentLen, ! 1179: /* length of encoded, encrypted content */ ! 1180: unsigned char *encryptedKey, /* encoded, encrypted DES key */ ! 1181: unsigned int encryptedKeyLen, ! 1182: /* length of encoded, encrypted DES key */ ! 1183: unsigned char *encryptedSignature,/* encoded, encrypted signature */ ! 1184: unsigned int encryptedSignatureLen, ! 1185: /* length of encoded, encrypted signature */ ! 1186: unsigned char iv[8], /* DES initialization vector */ ! 1187: int digestAlgorithm, /* message-digest algorithm */ ! 1188: R_RSA_PRIVATE_KEY *privateKey, /* recipient's RSA private key */ ! 1189: R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ ! 1190: ); ! 1191: ! 1192: R_OpenPEMBlock decrypts an encrypted message and verifies a digital ! 1193: signature. Its operation is the inverse of R_SealPEMBlock. ! 1194: ! 1195: contentLen will not be greater than ! 1196: DECRYPTED_CONTENT_LEN(encryptedContentLen). ! 1197: ! 1198: Return value: 0 success ! 1199: RE_CONTENT_ENCODING encryptedContent has RFC 1421 encoding error ! 1200: RE_KEY_ENCODING encryptedKey has RFC 1421 encoding error ! 1201: RE_SIGNATURE_ENCODING encryptedSignature has RFC 1421 encoding ! 1202: error ! 1203: RE_PUBLIC_KEY publicKey cannot decrypt signature ! 1204: RE_PRIVATE_KEY privateKey cannot decrypt encrypted key ! 1205: RE_KEY recovered DES key cannot decrypt encrypted ! 1206: content or encrypted signature ! 1207: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1208: RE_SIGNATURE signature on content is incorrect ! 1209: ! 1210: ! 1211: R_DigestBlock ! 1212: ! 1213: int R_DigestBlock ( ! 1214: unsigned char *digest, /* message digest */ ! 1215: unsigned int *digestLen, /* length of message digest */ ! 1216: unsigned char *content, /* content */ ! 1217: unsigned int contentLen, /* length of content */ ! 1218: int digestAlgorithm /* message-digest algorithm */ ! 1219: ); ! 1220: ! 1221: R_DigestBlock computes the message digest of content, storing the ! 1222: resulting message digest in digest and its length in bytes in ! 1223: digestLen. ! 1224: ! 1225: digestAlgorithm is the algorithm with which the content is digested, ! 1226: and must be one of the values in Appendix D. ! 1227: ! 1228: digestLen will not be greater than MAX_DIGEST_LEN. ! 1229: ! 1230: Return value: 0 success ! 1231: RE_DIGEST_ALGORITHM digestAlgorithm is invalid ! 1232: ! 1233: ! 1234: 8. RUN-TIME LIBRARY ! 1235: ! 1236: RSAREF operates on memory blocks with three platform-specific library ! 1237: procedures that are modeled after conventional C library functions: ! 1238: ! 1239: R_memcmp compares two blocks of memory ! 1240: R_memcpy copies a block of memory ! 1241: R_memset sets a block of memory to a given value ! 1242: ! 1243: These procedures can be found in the file 'r_stdlib.c'. ! 1244: ! 1245: ! 1246: R_memcmp ! 1247: ! 1248: int R_memcmp ( ! 1249: POINTER firstBlock, /* first block */ ! 1250: POINTER secondBlock, /* second block */ ! 1251: unsigned int len /* length of blocks */ ! 1252: ); ! 1253: ! 1254: R_memcmp compares the first len bytes of firstBlock and secondBlock. ! 1255: The value of len can be zero, in which case firstBlock and secondBlock ! 1256: are undefined and R_memcmp returns 0. R_memcmp compares the blocks by ! 1257: scanning the blocks from lowest address to highest until a difference ! 1258: is found. The smaller-valued block is the one with the smaller-valued ! 1259: byte at the point of difference. If no difference is found, the ! 1260: blocks are equal. ! 1261: ! 1262: Return value: < 0 firstBlock is smaller ! 1263: 0 blocks are equal ! 1264: > 0 firstBlock is larger ! 1265: ! 1266: ! 1267: R_memcpy ! 1268: ! 1269: void R_memcpy ( ! 1270: POINTER output, /* output block */ ! 1271: POINTER input, /* input block */ ! 1272: unsigned int len /* length of blocks */ ! 1273: ); ! 1274: ! 1275: R_memcpy copies the first len bytes of input to output. The value of ! 1276: len can be zero, in which output and input are undefined. The blocks ! 1277: do not overlap. ! 1278: ! 1279: No return value. ! 1280: ! 1281: ! 1282: R_memset ! 1283: ! 1284: void R_memset ( ! 1285: POINTER output, /* output block */ ! 1286: int value, /* value */ ! 1287: unsigned int len /* length of block */ ! 1288: ); ! 1289: ! 1290: R_memset sets the first len bytes of output to value. The value of ! 1291: len is zero, in which case output is undefined. ! 1292: ! 1293: No return value. ! 1294: ! 1295: ! 1296: APPENDIX A: RSAREF ERROR TYPES ! 1297: ! 1298: This appendix lists RSAREF's error types. ! 1299: ! 1300: RE_DATA other party's private value out of range ! 1301: ! 1302: RE_CONTENT_ENCODING content, encrypted content, or encoded block ! 1303: has RFC 1421 encoding error ! 1304: ! 1305: RE_DIGEST_ALGORITHM message-digest algorithm is invalid ! 1306: ! 1307: RE_ENCODING encoded block has RFC 1421 encoding error ! 1308: ! 1309: RE_ENCRYPTION_ALGORITHM encryption algorithm is invalid ! 1310: ! 1311: RE_KEY recovered DES key cannot decrypt encrypted ! 1312: content or encrypted signature ! 1313: ! 1314: RE_KEY_ENCODING encrypted key has RFC 1421 encoding error ! 1315: ! 1316: RE_LEN encrypted key length or signature length ! 1317: out of range ! 1318: ! 1319: RE_MODULUS_LEN modulus length out of range ! 1320: ! 1321: RE_NEED_RANDOM random structure is not seeded ! 1322: ! 1323: RE_PRIVATE_KEY private key cannot encrypt message digest, ! 1324: or cannot decrypt encrypted key ! 1325: ! 1326: RE_PUBLIC_KEY public key cannot encrypt data encryption ! 1327: key, or cannot decrypt signature ! 1328: ! 1329: RE_SIGNATURE signature on content or block is incorrect ! 1330: ! 1331: RE_SIGNATURE_ENCODING signature or encrypted signature has RFC 1421 ! 1332: encoding error ! 1333: ! 1334: ! 1335: APPENDIX B: RSAREF TYPES ! 1336: ! 1337: This appendix lists four RSAREF types: R_RSA_PUBLIC_KEY, ! 1338: R_RSA_PRIVATE_KEY, R_RSA_PROTO_KEY, and R_DH_PARAMS. ! 1339: ! 1340: ! 1341: R_RSA_PUBLIC_KEY ! 1342: ! 1343: typedef struct { ! 1344: unsigned int bits; /* length in bits of modulus */ ! 1345: unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ ! 1346: unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ ! 1347: } R_RSA_PUBLIC_KEY; ! 1348: ! 1349: An R_RSA_PUBLIC_KEY value is a structure specifying an RSA public key. ! 1350: There are three fields: ! 1351: ! 1352: bits length in bits of the modulus (not less than ! 1353: MIN_RSA_MODULUS_BITS and not greater than ! 1354: MAX_RSA_MODULUS_BITS) ! 1355: ! 1356: modulus modulus n, represented as a ! 1357: MAX_RSA_MODULUS_LEN-byte number, most ! 1358: significant byte first, as many leading zero ! 1359: bytes as necessary ! 1360: ! 1361: exponent public exponent e, represented like modulus ! 1362: ! 1363: ! 1364: R_RSA_PRIVATE_KEY ! 1365: ! 1366: typedef struct { ! 1367: unsigned int bits; /* length in bits of modulus */ ! 1368: unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ ! 1369: unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; ! 1370: /* public exponent */ ! 1371: unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ ! 1372: unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ ! 1373: unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; ! 1374: /* exponents for CRT */ ! 1375: unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */ ! 1376: } R_RSA_PRIVATE_KEY; ! 1377: ! 1378: An R_RSA_PRIVATE_KEY value is a structure specifying an RSA private ! 1379: key. There are seven fields: ! 1380: ! 1381: bits length in bits of the modulus (not less than ! 1382: MIN_RSA_MODULUS_BITS and not greater than ! 1383: MAX_RSA_MODULUS_BITS) ! 1384: ! 1385: modulus modulus n, represented as a ! 1386: MAX_RSA_MODULUS_LEN-byte number, most ! 1387: significant byte first, as many leading zero ! 1388: bytes as necessary ! 1389: ! 1390: publicExponent public exponent e, represented like modulus ! 1391: ! 1392: exponent private exponent d, represented like modulus ! 1393: ! 1394: prime prime factors p and q of modulus, each ! 1395: represented as MAX_RSA_PRIME_LEN-byte ! 1396: numbers, most significant byte first, as ! 1397: many leading zero bytes as necessary, where ! 1398: p > q ! 1399: ! 1400: primeExponents exponents (d mod p-1) and (d mod q-1) for ! 1401: Chinese remainder theorem (CRT) operations, ! 1402: each represented like prime factors ! 1403: ! 1404: coefficient coefficient (q^{-1} mod p) for Chinese ! 1405: remainder theorem operations, represented ! 1406: like prime factors ! 1407: ! 1408: ! 1409: R_RSA_PROTO_KEY ! 1410: ! 1411: typedef struct { ! 1412: unsigned int bits; /* length in bits of modulus */ ! 1413: int useFermat4; /* public exponent (1 = F4, 0 = 3) */ ! 1414: } R_RSA_PROTO_KEY; ! 1415: ! 1416: An R_RSA_PROTO_KEY value is a structure specifying the length in bits ! 1417: of the RSA modulus and the public exponent for key-pair generation. ! 1418: There are two fields: ! 1419: ! 1420: bits length in bits of the modulus (not less than ! 1421: MIN_RSA_MODULUS_BITS and not greater than ! 1422: MAX_RSA_MODULUS_BITS) ! 1423: ! 1424: useFermat4 a flag specifying the public exponent. If ! 1425: nonzero, it specifies F4 (65537); if 0, F0 ! 1426: (3) ! 1427: ! 1428: ! 1429: R_DH_PARAMS ! 1430: ! 1431: typedef struct { ! 1432: unsigned char *prime; /* prime */ ! 1433: unsigned int primeLen; /* length of prime */ ! 1434: unsigned char *generator; /* generator */ ! 1435: unsigned int generatorLen; /* length of generator */ ! 1436: } R_DH_PARAMS; ! 1437: ! 1438: An R_DH_PARAMS value is a structure specifying Diffie-Hellman ! 1439: parameters. There are four fields: ! 1440: ! 1441: prime prime p, represented as a primeLen-byte ! 1442: number, most significant byte first, as ! 1443: many leading zero bytes as necessary ! 1444: ! 1445: primeLen length in bytes of the prime ! 1446: ! 1447: generator generator g, represented like prime ! 1448: ! 1449: generatorLen length in bytes of the generator ! 1450: ! 1451: ! 1452: APPENDIX C: PLATFORM-SPECIFIC TYPES AND CONSTANTS ! 1453: ! 1454: This appendix lists three platform-specific types and one #define'd ! 1455: constant. ! 1456: ! 1457: ! 1458: TYPES ! 1459: ! 1460: RSAREF requires three platform-specific types: POINTER, UINT2, and ! 1461: UINT4. These are defined in the file 'global.h'. ! 1462: ! 1463: ! 1464: POINTER ! 1465: ! 1466: A POINTER value is a generic pointer to memory to which any other ! 1467: pointer can be cast. ! 1468: ! 1469: Example: ! 1470: ! 1471: typedef unsigned char *POINTER; ! 1472: ! 1473: ! 1474: UINT2 ! 1475: ! 1476: A UINT2 value is a 16-bit unsigned integer. ! 1477: ! 1478: Example: ! 1479: ! 1480: typedef unsigned short int UINT2; ! 1481: ! 1482: ! 1483: UINT4 ! 1484: ! 1485: A UINT4 value is a 32-bit unsigned integer. ! 1486: ! 1487: Example: ! 1488: ! 1489: typedef unsigned long int UINT4; ! 1490: ! 1491: ! 1492: #DEFINE'D CONSTANTS ! 1493: ! 1494: RSAREF requires one #define'd constant: PROTOTYPES. This is defined ! 1495: in the 'makefile' on the C compiler command line. ! 1496: ! 1497: PROTOTYPES indicates the form that C function declarations are to ! 1498: take. If PROTOTYPES is nonzero, declarations take the form ! 1499: ! 1500: type function (type, ..., type); ! 1501: ! 1502: Otherwise declarations take the form ! 1503: ! 1504: type function (); ! 1505: ! 1506: ! 1507: APPENDIX D: ENCRYPTION ALGORITHMS AND IDENTIFIERS ! 1508: ! 1509: This appendix lists message-digest and data encryption algorithms and ! 1510: their identifiers. ! 1511: ! 1512: ! 1513: D.1 Message-digest algorithms ! 1514: ! 1515: RSAREF supports two message-digest algorithms, listed here with their ! 1516: integer identifiers: ! 1517: ! 1518: DA_MD2 MD2 message-digest algorithm [3] ! 1519: ! 1520: DA_MD5 MD5 message-digest algorithm [4] ! 1521: ! 1522: ! 1523: D.2 Data encryption algorithms ! 1524: ! 1525: RSAREF supports four data encryption algorithms, listed here with ! 1526: their integer identifiers: ! 1527: ! 1528: EA_DES_CBC Data Encryption Standard [5] in cipher-block ! 1529: chaining (CBC) mode [6] ! 1530: ! 1531: EA_DESX_CBC RSA Data Security's DESX enhancement of DES, ! 1532: in CBC mode (this algorithm exclusive-ors ! 1533: with the previous ciphertext block, ! 1534: exclusive-ors with a secret value, encrypts ! 1535: with DES, then exclusive-ors with a second ! 1536: secret value) ! 1537: ! 1538: EA_DES_EDE3_CBC Three-key triple-DES in CBC mode (this ! 1539: algorithm exclusive-ORs with the previous ! 1540: ciphertext block, encrypts with one DES ! 1541: key, decrypts with a second DES key, then ! 1542: encrypts with a third DES key) ! 1543: ! 1544: EA_DES_EDE2_CBC Two-key triple-DES in CBC mode (like three- ! 1545: key, except that the first and third DES ! 1546: keys are the same) ! 1547: ! 1548: All four algorithms have a block size of eight bytes, and hence an ! 1549: eight-byte initialization vector. All employ the padding rules ! 1550: described in RFC 1423 [11]. ! 1551: ! 1552: ! 1553: REFERENCES ! 1554: ! 1555: [1] R.L. Rivest, A. Shamir, and L. Adleman. A method for obtaining ! 1556: digital signatures and public-key cryptosystems. Communications ! 1557: of the ACM, 21(2):120-126, February 1978. ! 1558: ! 1559: [2] RSA Laboratories. PKCS #1: RSA Encryption Standard. Version 1.5, ! 1560: November 1993. (PKCS documents are available via electronic mail ! 1561: to <[email protected]>.) ! 1562: ! 1563: [3] B. Kaliski. RFC 1319: The MD2 Message-Digest Algorithm. April ! 1564: 1992. ! 1565: ! 1566: [4] R. Rivest. RFC 1321: The MD5 Message-Digest Algorithm. April ! 1567: 1992. ! 1568: ! 1569: [5] National Bureau of Standards. FIPS Publication 46-1: Data ! 1570: Encryption Standard. January 1988. ! 1571: ! 1572: [6] National Bureau of Standards. FIPS Publication 81: DES Modes of ! 1573: Operation. December 1980. ! 1574: ! 1575: [7] W. Diffie and M.E. Hellman. New directions in cryptography. IEEE ! 1576: Transactions on Information Theory, IT-22:644-654, 1976. ! 1577: ! 1578: [8] RSA Laboratories. PKCS #3: Diffie-Hellman Key-Agreement Standard. ! 1579: Version 1.4, November 1993. ! 1580: ! 1581: [9] J. Linn. RFC 1421: Privacy Enhancement for Internet Electronic ! 1582: Mail: Part I: Message Encryption and Authentication Procedures. ! 1583: February 1993. ! 1584: ! 1585: [10] S. Kent. RFC 1422: Privacy Enhancement for Internet Electronic ! 1586: Mail: Part II: Certificate-Based Key Management. February 1993. ! 1587: ! 1588: [11] D. Balenson. RFC 1423: Privacy Enhancement for Internet ! 1589: Electronic Mail: Part III: Algorithms, Modes, and Identifiers. ! 1590: February 1993. ! 1591: ! 1592: [12] B. Kaliski. RFC 1424: Privacy Enhancement for Internet Electronic ! 1593: Mail: Part IV: Key Certification and Related Services. February ! 1594: 1993. ! 1595: ! 1596: [13] RSA Laboratories. PKCS #7: Cryptographic Message Syntax Standard. ! 1597: Version 1.5, November 1993. ! 1598: ! 1599: [14] RSA Laboratories. PKCS #10: Certification Request Syntax ! 1600: Standard. Version 1.0, November 1993.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.