Annotation of rsaref/doc/rsaref.txt, revision 1.1.1.2

1.1.1.2 ! root        1:                  RSAREF(TM): A Cryptographic Toolkit
1.1       root        2:                        Library Reference Manual
                      3: 
                      4:                            RSA Laboratories
1.1.1.2 ! root        5:                             March 21, 1994
1.1       root        6: 
1.1.1.2 ! root        7:                              Version 2.0
        !             8: 
        !             9:     Copyright (C) 1991-4 RSA Laboratories, a division of RSA Data
1.1       root       10:                  Security, Inc. All rights reserved.
                     11: 
                     12: 
1.1.1.2 ! root       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]
1.1       root       28: 
1.1.1.2 ! root       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
1.1       root       34: 
                     35: RSAREF is written entirely in C. Its application interface includes
                     36: the following routines:
                     37: 
1.1.1.2 ! root       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: 
1.1       root       85:       R_SignPEMBlock     computes a digital signature on a message
1.1.1.2 ! root       86:          R_SignBlock     computes a digital signature on a block of
        !            87:                            data such as a certificate
1.1       root       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: 
1.1.1.2 ! root       97:        R_DigestBlock     computes the message digest of a message
1.1       root       98: 
1.1.1.2 ! root       99: This manual is divided into eight sections and three appendices.
1.1       root      100: 
1.1.1.2 ! root      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.
1.1       root      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: 
1.1.1.2 ! root      112: 2. RANDOM STRUCTURES
1.1       root      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: 
1.1.1.2 ! root      121: RSAREF sets up a random structure with the procedure R_RandomInit. A
        !           122: typical application calls R_RandomInit on entry.
1.1       root      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: 
1.1.1.2 ! root      142: R_RandomInit sets up a new random structure.
1.1       root      143: 
1.1.1.2 ! root      144: Return value:      0     success
        !           145:              nonzero     reserved for future compatibility
1.1       root      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: 
1.1.1.2 ! root      158: Return value:      0     success
        !           159:              nonzero     reserved for future compatibility
1.1       root      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: 
1.1.1.2 ! root      172: Return value:      0     success
        !           173:              nonzero     reserved for future compatibility
1.1       root      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: 
1.1.1.2 ! root      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: 
1.1       root      648: 
1.1.1.2 ! root      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,
1.1       root      860: R_VerifyBlockSignature, R_SealPEMBlock, R_OpenPEMBlock, and
                    861: R_DigestBlock.
                    862: 
1.1.1.2 ! root      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.
1.1       root      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
1.1.1.2 ! root      875:        (see Appendix D)
1.1       root      876:   -  a flag indicating whether to encode the message in printable
1.1.1.2 ! root      877:        ASCII according to RFC 1421
1.1       root      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
1.1.1.2 ! root      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.
1.1       root      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
1.1.1.2 ! root      904:        (see Appendix D)
1.1       root      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
1.1.1.2 ! root      912: content if the message was encoded.
1.1       root      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
1.1.1.2 ! root      921:        (see Appendix D)
1.1       root      922:   -  the signer's RSA public key
                    923: 
                    924: R_VerifyBlockSignature verifies the signature on the message with the
1.1.1.2 ! root      925: signer's public key and the specified message-digest algorithm.
1.1       root      926: 
1.1.1.2 ! root      927: To sign and encrypt a message, an application calls R_SealPEMBlock,
        !           928: giving these arguments:
1.1       root      929: 
                    930:   -  a pointer to the message content, and the message length
                    931:   -  an integer identifying which message-digest algorithm to apply
1.1.1.2 ! root      932:        (see Appendix D)
1.1       root      933:   -  the signer's RSA private key
                    934:   -  the recipient's RSA public key
1.1.1.2 ! root      935:   -  a random structure
1.1       root      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
1.1.1.2 ! root      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.
1.1       root      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
1.1.1.2 ! root      955:        (see Appendix D)
1.1       root      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
1.1.1.2 ! root      963: algorithm. It returns the message content.
1.1       root      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
1.1.1.2 ! root      970:        (see Appendix D)
1.1       root      971: 
                    972: R_DigestBlock digests the block with the specified message-digest
1.1.1.2 ! root      973: algorithm. It returns the message digest.
1.1       root      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: 
1.1.1.2 ! root      997:      1.   It digests content with digestAlgorithm, giving a message
1.1       root      998:           digest.
                    999: 
1.1.1.2 ! root     1000:      2.   It encrypts the message digest with privateKey, giving a
1.1       root     1001:           digital signature, and encodes the result in printable
1.1.1.2 ! root     1002:           ASCII according to RFC 1421, storing the encoding in
1.1       root     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
1.1.1.2 ! root     1009: according to RFC 1421. (It will not contain any line delimiters; the
1.1       root     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
1.1.1.2 ! root     1016: 1421. encodedSignatureLen will not be greater than
1.1       root     1017: MAX_PEM_SIGNATURE_LEN.
                   1018: 
1.1.1.2 ! root     1019: digestAlgorithm is the algorithm with which the message content is
        !          1020: digested, and must be one of the values listed in Appendix D.
1.1       root     1021: 
1.1.1.2 ! root     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
1.1       root     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
1.1.1.2 ! root     1067: nonzero, it first decodes encodedContent according to RFC 1421, and
1.1       root     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: 
1.1.1.2 ! root     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
1.1       root     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
1.1.1.2 ! root     1095: arbitrary byte strings, rather than RFC 1421-encoded strings.
1.1       root     1096: 
1.1.1.2 ! root     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
1.1       root     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 */
1.1.1.2 ! root     1115:   unsigned char iv[8],                 /* DES initialization vector */
1.1       root     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: 
1.1.1.2 ! root     1128:      1.   It digests content with digestAlgorithm, giving a message
1.1       root     1129:           digest.
                   1130: 
1.1.1.2 ! root     1131:      2.   It encrypts the message digest with privateKey, giving a
1.1       root     1132:           digital signature.
                   1133: 
1.1.1.2 ! root     1134:      3.   It generates a random DES key and initialization vector,
        !          1135:           storing the initialization vector in iv.
1.1       root     1136: 
1.1.1.2 ! root     1137:      4.   It encrypts content with the DES key and initialization vector
1.1       root     1138:           in cipher-block chaining mode, and encodes the result in
1.1.1.2 ! root     1139:           printable ASCII according to RFC 1421, storing the encoding
1.1       root     1140:           in encryptedContent.
                   1141: 
1.1.1.2 ! root     1142:      5.   It encrypts the DES key with publicKey and encodes the
1.1       root     1143:           result in printable ASCII, storing the encoding in
                   1144:           encryptedKey.
                   1145: 
1.1.1.2 ! root     1146:      6.   It encrypts the digital signature with the DES key and
        !          1147:           initialization vector, and encodes the result in printable
1.1       root     1148:           ASCII, storing the encoding in encryptedSignature.
                   1149: 
                   1150: encryptedContent will be an ASCII string, encoded according to RFC
1.1.1.2 ! root     1151: 1421. (It will not contain any line delimiters; the application must
1.1       root     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
1.1.1.2 ! root     1156: according to RFC 1421. encryptedKeyLen will not be greater than
1.1       root     1157: MAX_PEM_ENCRYPTED_KEY_LEN. encryptedSignatureLen will not be greater
                   1158: than MAX_PEM_ENCRYPTED_SIGNATURE_LEN.
                   1159: 
1.1.1.2 ! root     1160: digestAlgorithm is the algorithm with which the message content is
        !          1161: digested, and must be one of the values listed in Appendix D.
1.1       root     1162: 
                   1163: randomStruct must have been seeded.
                   1164: 
1.1.1.2 ! root     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
1.1       root     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 */
1.1.1.2 ! root     1186:   unsigned char iv[8],                 /* DES initialization vector */
1.1       root     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
1.1.1.2 ! root     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
1.1       root     1202:                            error
1.1.1.2 ! root     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
1.1       root     1206:                            content or encrypted signature
1.1.1.2 ! root     1207:  RE_DIGEST_ALGORITHM     digestAlgorithm is invalid
        !          1208:         RE_SIGNATURE     signature on content is incorrect
1.1       root     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: 
1.1.1.2 ! root     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.
1.1       root     1224: 
1.1.1.2 ! root     1225: digestAlgorithm is the algorithm with which the content is digested,
        !          1226: and must be one of the values in Appendix D.
1.1       root     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: 
1.1.1.2 ! root     1234: 8. RUN-TIME LIBRARY
1.1       root     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: 
1.1.1.2 ! root     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
1.1       root     1304: 
1.1.1.2 ! root     1305:  RE_DIGEST_ALGORITHM     message-digest algorithm is invalid
1.1       root     1306: 
1.1.1.2 ! root     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
1.1       root     1312:                            content or encrypted signature
                   1313: 
1.1.1.2 ! root     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
1.1       root     1318: 
1.1.1.2 ! root     1319:       RE_MODULUS_LEN     modulus length out of range
1.1       root     1320: 
1.1.1.2 ! root     1321:       RE_NEED_RANDOM     random structure is not seeded
1.1       root     1322: 
1.1.1.2 ! root     1323:       RE_PRIVATE_KEY     private key cannot encrypt message digest,
1.1       root     1324:                            or cannot decrypt encrypted key
                   1325: 
1.1.1.2 ! root     1326:        RE_PUBLIC_KEY     public key cannot encrypt data encryption
        !          1327:                            key, or cannot decrypt signature
1.1       root     1328: 
1.1.1.2 ! root     1329:         RE_SIGNATURE     signature on content or block is incorrect
1.1       root     1330: 
1.1.1.2 ! root     1331: RE_SIGNATURE_ENCODING    signature or encrypted signature has RFC 1421
1.1       root     1332:                            encoding error
                   1333: 
                   1334: 
                   1335: APPENDIX B: RSAREF TYPES
                   1336: 
1.1.1.2 ! root     1337: This appendix lists four RSAREF types: R_RSA_PUBLIC_KEY,
        !          1338: R_RSA_PRIVATE_KEY, R_RSA_PROTO_KEY, and R_DH_PARAMS.
1.1       root     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: 
1.1.1.2 ! root     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: 
1.1       root     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: 
1.1.1.2 ! root     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: 
1.1       root     1553: REFERENCES
                   1554: 
1.1.1.2 ! root     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.
1.1       root     1565: 
1.1.1.2 ! root     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
1.1       root     1570:      Encryption Standard. January 1988.
                   1571: 
1.1.1.2 ! root     1572: [6]  National Bureau of Standards. FIPS Publication 81: DES Modes of
1.1       root     1573:      Operation. December 1980.
                   1574: 
1.1.1.2 ! root     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.

unix.superglobalmegacorp.com

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