--- pgp/rsaref/doc/rsaref.txt 2018/04/24 16:40:41 1.1 +++ pgp/rsaref/doc/rsaref.txt 2018/04/24 16:41:51 1.1.1.2 @@ -1,1600 +1,806 @@ - RSAREF(TM): A Cryptographic Toolkit - Library Reference Manual - - RSA Laboratories - March 21, 1994 - - Version 2.0 - - Copyright (C) 1991-4 RSA Laboratories, a division of RSA Data - Security, Inc. All rights reserved. - - -1. INTRODUCTION - -This manual is a reference guide for users of RSAREF, RSA -Laboratories' portable, educational, reference implementation of -cryptography. - -RSAREF supports the following algorithms: - - o RSA encryption and key generation [1], as defined by RSA - Laboratories' Public-Key Cryptography Standards (PKCS) [2] - - o MD2 and MD5 message digests [3,4] - - o DES (Data Encryption Standard) in cipher-block chaining mode - [5,6] - - o Diffie-Hellman key agreement [7], as defined by PKCS #3 [8] - - o DESX, RSA Data Security's efficient, secure DES enhancement - - o Triple-DES, for added security with three DES operations - -RSAREF is written entirely in C. Its application interface includes -the following routines: - - R_SignInit, computes a digital signature on data of - R_SignUpdate, arbitrary length, processing in parts - and R_SignFinal - - R_VerifyInit, verifies a digital signature, processing in - R_VerifyUpdate, parts - and R_VerifyFinal - - R_SealInit, creates a digital envelope on data of - R_SealUpdate, arbitrary length, processing in parts - and R_SealFinal - - R_OpenInit, opens a digital envelope, processing in - R_OpenUpdate, parts - and R_OpenFinal - - R_DigestInit, digests data of arbitrary length, processing - R_DigestUpdate, in parts - and R_DigestFinal - - R_EncodePEMBlock encodes a message in printable ASCII - according to RFC 1421 [9] - R_DecodePEMBlock decodes a message encoded according to RFC - 1421 - - R_GeneratePEMKeys generates an RSA public/private key pair - - R_RandomInit initializes a random structure - R_RandomUpdate mixes bytes into a random structure -R_GetRandomBytesNeeded computes the number of mix-in bytes still - needed to seed a random structure - R_RandomFinal zeroizes a random structure - - R_GenerateDHParams generates Diffie-Hellman parameters - R_SetupDHAgreement sets up a key agreement - R_ComputeDHAgreedKey computes the agreed-upon key - -An Internet Privacy-Enhanced Mail [9-12] implementation can be built -directly on top of these routines, together with message parsing and -formatting routines and certificate-management routines. -Implementations of PKCS #7 and #10 [13,14] can be built in a similar -manner. Other secure applications can be built on top of the -Diffie-Hellman routines. - -The following routines are supported for backward compatibility with -RSAREF 1.0: - - R_SignPEMBlock computes a digital signature on a message - R_SignBlock computes a digital signature on a block of - data such as a certificate -R_VerifyPEMSignature verifies a digital signature on a message -R_VerifyBlockSignature verifies a digital signature on a block of - data such as a certificate - - R_SealPEMBlock computes a digital signature and encrypts a - message - R_OpenPEMBlock decrypts an encrypted message and verifies a - digital signature - - R_DigestBlock computes the message digest of a message - -This manual is divided into eight sections and three appendices. - -This section introduces RSAREF. The next six sections explain RSAREF -procedures: random structures; cryptographic enhancements; printable -ASCII encoding and decoding; key-pair generation; Diffie-Hellman key -agreement; and version 1.0 routines. The last section documents the -platform-specific run-time library. - -Appendix A lists RSAREF error types. Appendix B lists RSAREF types -and constants. Appendix C lists platform-specific types and -constants. - - -2. RANDOM STRUCTURES - -A random structure contains a seed from which a pseudorandom sequence -of bytes is derived. RSAREF generates keys and pads RSA encryption -blocks with bytes derived from a random structure. - -Random structures are used by both message-processing and -key-generation applications. - -RSAREF sets up a random structure with the procedure R_RandomInit. A -typical application calls R_RandomInit on entry. - -A new random structure is not ready for use until it is seeded by -mixing in some random bytes. RSAREF seeds a random structure with the -procedure R_RandomUpdate and R_GetRandomBytesNeeded. A random -structure is considered seeded when the number of bytes still needed -reaches zero. More bytes can be mixed in after the random structure -is seeded. A typical application calls R_GetRandomBytesNeeded and -R_RandomUpdate immediately after calling R_RandomInit. - -RSAREF zeroizes a random structure with the procedure R_RandomFinal. -A typical application calls R_RandomFinal on exit. - - -R_RandomInit - -int R_RandomInit ( - R_RANDOM_STRUCT *randomStruct /* new random structure */ -); - -R_RandomInit sets up a new random structure. - -Return value: 0 success - nonzero reserved for future compatibility - - -R_RandomUpdate - -int R_RandomUpdate ( - R_RANDOM_STRUCT *randomStruct, /* random structure */ - unsigned char *block, /* block of values to mix in */ - unsigned int blockLen /* length of block */ -); - -R_RandomUpdate mixes blockLen bytes from block into randomStruct. - -Return value: 0 success - nonzero reserved for future compatibility - - -R_GetRandomBytesNeeded - -int R_GetRandomBytesNeeded ( - unsigned int *bytesNeeded, /* number of mix-in bytes needed */ - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_GetRandomBytesNeeded computes the number of mix-in bytes still -needed to seed randomStruct, storing the result in bytesNeeded. - -Return value: 0 success - nonzero reserved for future compatibility - - -R_RandomFinal - -void R_RandomFinal ( - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_RandomFinal zeroizes randomStruct. - -No return value. - - -3. CRYPTOGRAPHIC ENHANCEMENTS - -RSAREF's cryptographic enhancements fall into five groups: signing -data; verifying signatures; sealing data in digital envelopes; -opening digital envelopes; and digesting data. - -All the procedures process data in parts; it is not necessary for all -data to be stored in memory at once. - - -3.1 Signing data - -RSAREF signs data with three procedures: R_SignInit, R_SignUpdate, -and R_SignFinal. These procedures are typically called by -message-processing applications, by key-generation applications when -constructing a PEM or PKCS certification request, and by -certification applications when signing a certificate. - -An application first calls R_SignInit, giving an integer specifying -which message-digest algorithm to apply (see Appendix D). R_SignInit -sets up a context for the signature operation, and returns the -context. - -The application then calls R_SignUpdate any number of times, giving -the context and the next data part. R_SignUpdate digests the part. - -After all the parts are supplied, the application calls R_SignFinal, -giving the context and the signer's RSA private key. R_SignFinal -encrypts the message digest with the private key and returns the -result, which is the signature. - -An application may call R_SignUpdate again after R_SignFinal to -sign other data, without setting up a new context. - - -R_SignInit - -int R_SignInit ( - R_SIGNATURE_CTX *context, /* new context */ - int digestAlgorithm /* message-digest algorithm */ -); - -R_SignInit begins a signature operation, setting up a new context. - -digestAlgorithm is the algorithm with which data are digested, and -must be one of the values listed in Appendix D. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - - -R_SignUpdate - -int R_SignUpdate ( - R_SIGNATURE_CTX *context, /* context */ - unsigned char *partIn, /* next data part */ - unsigned char partInLen /* length of next data part */ -); - -R_SignUpdate continues a signature operation, digesting partIn, the -next data part, with the specified message-digest algorithm. It may -be called any number of times. - -Return value: 0 success - - -R_SignFinal - -int R_SignFinal ( - R_SIGNATURE_CTX *context, /* context */ - unsigned char *signature, /* signature */ - unsigned int *signatureLen, /* length of signature */ - R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ -); - -R_SignFinal completes a signature operation, encrypting the message -digest with the signer's private key. It stores the resulting -signature in signature and its length in signatureLen. - -signatureLen will not be greater than MAX_SIGNATURE_LEN. - -Return value: 0 success - RE_PRIVATE_KEY privateKey cannot encrypt message digest - - -3.2 Verifying a signature - -RSAREF verifies signatures with three procedures: R_VerifyInit, -R_VerifyUpdate, and R_VerifyFinal. These procedures are typically -called by message-processing applications and by certification -applications when processing a certification request. - -An application first calls R_VerifyInit, giving an integer specifying -which message-digest algorithm to apply (see Appendix D). -R_VerifyInit sets up a context for the verification operation, and -returns the context. - -The application then calls R_VerifyUpdate any number of times, giving -the context and the next data part. R_VerifyUpdate digests the part. - -After all the parts are supplied, the application calls -R_VerifyFinal, giving the context, the signer's RSA public key, and -the signature. R_SignFinal decrypts the signature with the public key -and compares the result to the message digest to see whether the -signature is valid. - -An application may call R_VerifyUpdate again after R_VerifyFinal to -verify other signatures, without setting up a new context. - - -R_VerifyInit - -int R_VerifyInit ( - R_SIGNATURE_CTX *context, /* new context */ - int digestAlgorithm /* message-digest algorithm */ -); - -R_VerifyInit begins a verification operation, setting up a new -context. - -digestAlgorithm is the algorithm with which data are digested, and -must be one of the values listed in Appendix D. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - - -R_VerifyUpdate - -int R_VerifyUpdate ( - R_SIGNATURE_CTX *context, /* context */ - unsigned char *partIn, /* next data part */ - unsigned int partInLen /* length of next data part */ -); - -R_VerifyUpdate continues a verification operation, digesting partIn, -the next data part, with the specified message-digest algorithm. It -may be called any number of times. - -Return value: 0 success - - -R_VerifyFinal - -int R_VerifyFinal ( - R_SIGNATURE_CTX *context, /* context */ - unsigned char *signature, /* signature */ - unsigned int signatureLen, /* length of signature */ - R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ -); - -R_VerifyFinal completes a verification operation, decrypting the -signature with the signer's public key and comparing it to the -message digest. - -signatureLen must not be greater than MAX_SIGNATURE_LEN. - -Return value: 0 success - RE_LEN signatureLen out of range - RE_PUBLIC_KEY publicKey cannot decrypt signature - RE_SIGNATURE signature is incorrect - - -3.3 Sealing data in a digital envelope - -RSAREF seals data in digital envelopes with three procedures: -R_SealInit, R_SealUpdate, and R_SealFinal. There may be any number of -recipients. These procedures are typically called by -message-processing applications. - -An application first calls R_SealInit, giving an integer specifying -which data encryption algorithm to apply (see Appendix D), the public -key of each recipient, and a random structure. R_SealInit sets up a -context for the sealing operation, generates a data encryption key -and an initialization vector, and encrypts the data encryption key -with each recipient's public key. It returns the context, the -initialization vector, and the encrypted data encryption keys. - -The application then calls R_SealUpdate any number of times, giving -the context and the next data part. R_SealUpdate encrypts the part -and returns the next encrypted data part. (Depending on how data are -supplied, it may return more or less data than are supplied.) - -After all the parts are supplied, the application calls R_SealFinal, -giving the context. R_SealFinal returns the last encrypted data part. - -An application may call R_SealUpdate again after R_SealFinal to -encrypt other data under the same data encryption key and -initialization vector. This is useful when message content is signed -and encrypted, and the digital signature must also be encrypted. - - -R_SealInit - -int R_SealInit ( - R_ENVELOPE_CTX *context, /* new context */ - unsigned char **encryptedKeys, /* encrypted keys */ - unsigned int *encryptedKeyLens, /* lengths of encrypted keys */ - unsigned char iv[8], /* initialization vector */ - unsigned int publicKeyCount, /* number of public keys */ - R_RSA_PUBLIC_KEY **publicKeys, /* public keys */ - int encryptionAlgorithm, /* data encryption algorithm */ - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_SealInit begins a "sealing" operation. It performs the following -steps: - - 1. It sets up a new context. - - 2. It generates a random data encryption key and initialization - vector, storing the initialization vector in iv. - - 3. It encrypts the data encryption key with each recipient's - public key, storing the encrypted keys in encryptedKeys and - their lengths in encryptedKeyLens. (Note that each - encryptedKeys member should be a pointer, initialized by - the application.) - -The encryptedKeyLens members will not be greater than -MAX_ENCRYPTED_KEY_LEN. - -encryptionAlgorithm is the algorithm with which data are encrypted, -and must be one of the values listed in Appendix D. - -randomStruct must have been seeded. - -Return value: 0 success -RE_ENCRYPTION_ALGORITHM encryptionAlgorithm is invalid - RE_PUBLIC_KEY publicKey cannot encrypt data encryption - key - RE_NEED_RANDOM randomStruct is not seeded - - -R_SealUpdate - -int R_SealUpdate ( - R_ENVELOPE_CTX *context, /* context */ - unsigned char *partOut, /* next encrypted data part */ - unsigned int *partOutLen, /* length of next encrypted data part */ - unsigned char *partIn, /* next data part */ - unsigned int partInLen /* length of next data part */ -); - -R_SealUpdate continues a sealing operation, decrypting partIn, the -next data part, with the specified data encryption algorithm, and -returning partOut, the next encrypted data part. It may be called any -number of times. - -partOutLen will always be a multiple of 8, and it will not be greater -than partInLen+7. If partInLen is a multiple of 8, then partOutLen -will be the same as partInLen. - -(As a special case, if partInLen is a multiple of 24, then partOutLen -will be the same as partInLen; this is helpful when the output is to -be encoded in ASCII, since the length of each part input to -R_EncodePEMBlock should be a multiple of 3.) - -Return value: 0 success - - -R_SealFinal - -int R_SealFinal ( - R_ENVELOPE_CTX *context, /* context */ - unsigned char *partOut, /* last encrypted data part */ - unsigned int *partOutLen /* length of last encrypted data part */ -); - -R_SealFinal completes a sealing operation, returning partOut, the -last encrypted data part. - -partOutLen will always be 8. - -Return value: 0 success - - -3.4 Opening a digital envelope - -RSAREF opens digital envelopes with three procedures: R_OpenInit, -R_OpenUpdate, and R_OpenFinal. These procedures are typically called -by message-processing applications. - -An application first calls R_OpenInit, giving an integer specifying -which data encryption algorithm to apply (see Appendix D), an -initialization vector, the recipient's RSA private key, and an -encrypted data encryption key. R_OpenInit sets up a context for the -opening operation and decrypts the encrypted data encryption key with -the private key. It returns the context. - -The application then calls R_OpenUpdate any number of times, giving -the context and the next encrypted data part. R_OpenUpdate decrypts -the encrypted part and returns the next recovered data part. (Depending -on how data are supplied, it may return more or less data than are -supplied.) - -After all the parts are supplied, the application calls R_OpenFinal, -giving the context. R_OpenFinal returns the last recovered data part. - -As described for the sealing operations, an application may call -R_OpenUpdate again after R_OpenFinal to decrypt other data under the -same data encryption key and initialization vector. - - -R_OpenInit - -int R_OpenInit ( - R_ENVELOPE_CTX *context, /* new context */ - int encryptionAlgorithm, /* data encryption algorithm */ - unsigned char *encryptedKey, /* encrypted data encryption key */ - unsigned int encryptedKeyLen, /* length of encrypted key */ - unsigned char iv[8], /* initialization vector */ - R_RSA_PRIVATE_KEY *privateKey /* recipient's RSA private key */ -); - -R_OpenInit begins an "opening" operation, setting up a new context -and decrypting encryptedKey with privateKey. - -iv is the initialization vector for the data encryption algorithm. -encryptionAlgorithm is the algorithm with which the data is -encrypted, and must be one of the values listed in Appendix D. - -encryptedKeyLen must not be greater than MAX_ENCRYPTED_KEY_LEN. - -Return value: 0 success - RE_LEN encryptedKeyLen out of range -RE_ENCRYPTION_ALGORITHM encryptionAlgorithm is invalid - RE_PRIVATE_KEY privateKey cannot decrypt encrypted key - - -R_OpenUpdate - -int R_OpenUpdate ( - R_ENVELOPE_CTX *context, /* context */ - unsigned char *partOut, /* next recovered data part */ - unsigned int *partOutLen, /* length of next recovered data part */ - unsigned char *partIn, /* next encrypted data part */ - unsigned int partInLen /* length of next encrypted data part */ -); - -R_OpenUpdate continues an opening operation, decrypting partIn, the -next encrypted data part, and returning partOut, the next recovered -data part. It may be called any number of times. - -partOutLen will always be a multiple of 8, and it will not be greater -than partInLen+7. - -Return value: 0 success - - -R_OpenFinal - -int R_OpenFinal ( - R_ENVELOPE_CTX *context, /* context */ - unsigned char *partOut, /* last recovered data part */ - unsigned int *partOutLen /* length of last recovered data part */ -); - -R_SealFinal completes a sealing operation, returning partOut, the -last recovered data part. - -partOutLen will not be greater than 7. - -Return value: 0 success - RE_KEY recovered data encryption key cannot decrypt - encrypted data - -3.5 Digesting a message - -RSAREF digests messages with three procedures: R_DigestInit, -R_DigestUpdate, and R_DigestFinal. These procedures have no -particular PEM application, but may be useful in PKCS #7. - -An application first calls R_DigestInit, giving an integer specifying -which message-digest algorithm to apply (see Appendix D). -R_DigestInit sets up a context for the digesting operation, and -returns the context. - -The application then calls R_DigestUpdate any number of times, giving -the context and the next data part. R_DigestUpdate digests the part. - -After all the parts are supplied, the application calls -R_DigestFinal, giving the context. R_DigestFinal returns the message -digest. - -An application may call R_DigestUpdate again after R_DigestFinal to -digest other data, without setting up a new context. - - -R_DigestInit - -int R_DigestInit ( - R_DIGEST_CTX *context, /* new context */ - int digestAlgorithm /* message-digest algorithm */ -); - -R_DigestInit begins a message-digest operation, setting up a new -context. - -digestAlgorithm is the algorithm with which data are digested, and -must be one of the values listed in Appendix D. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - - -R_DigestUpdate - -int R_DigestUpdate ( - R_DIGEST_CTX *context, /* context */ - unsigned char *partIn, /* next data part */ - unsigned int partInLen /* length of next data part */ -); - -R_DigestUpdate continues a message-digest operation, digesting the -next data part with the specified message-digest algorithm. It may be -called any number of times. - -Return value: 0 success - - -R_DigestFinal - -int R_DigestFinal ( - R_DIGEST_CTX *context, /* context */ - unsigned char *digest, /* message digest */ - unsigned int *digestLen /* length of message digest */ -); - -R_DigestFinal completes a message-digest operation, storing the -message digest in digest and its length in bytes in digestLen. - -digestLen will not be greater than MAX_DIGEST_LEN. - -Return value: 0 success - - -4. ENCODING AND DECODING - -RSAREF encodes and decodes blocks of data in printable ASCII -according to RFC 1421 with two procedures: R_EncodePEMBlock -and R_DecodePEMBlock. They are typically called by -message-processing applications to format and parse fields -of the encapsulated header of a privacy-enhanced message, as -well as the message content. - -To encode a block in printable ASCII, an application calls -R_EncodePEMBlock, giving a pointer to the block and the block length. -R_EncodePEMBlock encodes the block in printable ASCII and returns the -encoded block. - -To decode a block encoded in printable ASCII, an application calls -R_DecodePEMBlock, giving a pointer to the encoded block, and the -encoded block length. R_DecodePEMBlock decodes the encoded block and -returns the decoded block. - -An application can process data in parts with these procedures, -provided that the length of each input part (except possibly the -last) is a multiple of the "quantum" size: three bytes for -encoding, four bytes for decoding. - - -R_EncodePEMBlock - -int R_EncodePEMBlock ( - unsigned char *encodedBlock, /* encoded block */ - unsigned int *encodedBlockLen, /* length of encoded block */ - unsigned char *block, /* block */ - unsigned int blockLen /* length of block */ -); - -R_EncodePEMBlock encodes block in printable ASCII according to RFC -1421, storing the encoding in encodedBlock. - -encodedBlock will be an ASCII string, encoded according to RFC 1421. -(It will not contain any line delimiters; the application must break -the string into lines.) encodedBlockLen will not be greater than -ENCODED_CONTENT_LEN(blockLen). - -When processing data in parts, blockLen should be a multiple of 3, -except possibly for the last part. - -Return value: 0 success - nonzero reserved for future compatibility - - -R_DecodePEMBlock - -int R_DecodePEMBlock (block, blockLen, encodedBlock, encodedBlockLen) - unsigned char *block, /* block */ - unsigned int *blockLen, /* length of block */ - unsigned char *encodedBlock, /* encoded block */ - unsigned int encodedBlockLen /* length of encoded block */ -); - -R_DecodePEMBlock decodes a block encoded according to RFC 1421. Its -operation is the reverse of R_EncodePEMBlock. - -blockLen will not be greater than -DECODED_CONTENT_LEN(encodedBlockLen). - -When processing data in parts, encodedBlockLen should be a multiple -of 4, except possibly for the last part. - -Return value: 0 success - RE_ENCODING encodedBlock has RFC 1421 encoding error - - -5. KEY-PAIR GENERATION - -RSAREF generates key pairs with the procedure R_GeneratePEMKeys. -R_GeneratePEMKeys is typically called by key generation applications. -To generate a new key pair, an application calls R_GeneratePEMKeys, -giving the length in bits of the modulus, the choice of public -exponent (3 or 65537), and a random structure. R_GeneratePEMKeys -generates an RSA key pair and returns the public and private keys. - - -R_GeneratePEMKeys - -int R_GeneratePEMKeys ( - R_RSA_PUBLIC_KEY *publicKey, /* new RSA public key */ - R_RSA_PRIVATE_KEY *privateKey, /* new RSA private key */ - R_RSA_PROTO_KEY *protoKey, /* RSA prototype key */ - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_GeneratePEMKeys generates a random RSA key pair, storing the -resulting RSA public key in publicKey and the resulting RSA private -key in privateKey. - -Other parameters are as follows: - - protoKey The RSA prototype key specifying the length - in bits of the RSA modulus and the public - exponent. (See Appendix B.) - - randomStruct Random structure from which the key pair is - derived. It must have been seeded. - -Return value: 0 success - RE_MODULUS_LEN modulus length invalid - RE_NEED_RANDOM randomStruct is not seeded - - -6. DIFFIE-HELLMAN KEY AGREEMENT - -To generate new Diffie-Hellman parameters, an application calls -R_GenerateDHParams, giving the length in bits of the Diffie-Hellman -prime and a random structure. R_GenerateDHParams generates the -parameters. Several users may share given Diffie-Hellman parameters, -or they may be unique to a given user. - -To set up a key agreement, communicating applications call -R_SetupDHAgreement, giving these parameters: - - - the Diffie-Hellman parameters - - a random structure - -R_SetupDHAgreement generates a new "public value" and a new "private -value" for each party. The applications then exchange their public -values. - -To compute the agreed-upon key, the applications call -R_ComputeDHAgreedKey, giving these parameters: - - - the Diffie-Hellman parameters - - the other party's public value - - the private value - -R_ComputeDHAgreedKey computes the agreed-upon key. - -The applications may encrypt subsequent data with the agreed-upon -key. When the length of the Diffie-Hellman prime is large enough, it -is considered impractical for someone who sees the Diffie-Hellman -parameters and the exchanged public values to determine to -agreed-upon key, so the subsequent encryption is secure. - - -R_GenerateDHParams - -int R_GenerateDHParams ( - R_DH_PARAMS *params, /* new Diffie-Hellman parameters */ - unsigned int primeBits, /* length in bits of prime */ - unsigned int subPrimeBits, /* length in bits of subprime */ - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_GenerateDHParams generates random Diffie-Hellman parameters, -storing the result in params. primeBits specifies the length in bits -of the Diffie-Hellman prime p, and subPrimeBits specifies the length -in bits of the prime q that divides p-1. The resulting generator g -has order q. - -The resulting params->primeLen and params->generatorLen will be at -most DH_PRIME_LEN (bits); params->prime and params->generator should -point to arrays at least that long. - -randomStruct must have been seeded. - -Return value: 0 success - RE_MODULUS_LEN prime length invalid - RE_NEED_RANDOM randomStruct is not seeded - - -R_SetupDHAgreement - -int R_SetupDHAgreement ( - unsigned char *publicValue, /* new public value */ - unsigned char *privateValue, /* new private value */ - unsigned int privateValueLen, /* length of private value */ - R_DH_PARAMS *params, /* Diffie-Hellman parameters */ - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_SetupDHAgreement sets up a Diffie-Hellman key agreement by -generating a public value and a private value from the Diffie-Hellman -parameters. It stores the resulting public value in publicValue and -the resulting private value in private value. - -The private value is a random number x whose length in bytes is -privateValueLen, and the public value is the number y such that - - y = g^x mod p, - -where p and g are the prime and generator in params. (Typically, one -selects privateValueLen according to the length in bits of the -"subprime" q.) - -publicValue and privateValue will be represented most significant -byte first, with no leading zero bytes. publicValue will have the -same length as the prime. - -randomStruct must have been seeded. - -Return value: 0 success - RE_NEED_RANDOM randomStruct is not seeded - - -R_ComputeDHAgreedKey - -int R_ComputeDHAgreedKey ( - unsigned char *agreedKey, /* new agreed-upon key */ - unsigned char *otherPublicValue, /* other's public value */ - unsigned char *privateValue, /* private value */ - unsigned int privateValueLen, /* length of private value */ - R_DH_PARAMS *params /* Diffie-Hellman parameters */ -); - -R_ComputeDHAgreedKey computes an agreed-upon key from the other -party's public value, a private value, and the Diffie-Hellman -parameters. It stores the resulting agreed key in agreedKey. - -The agreed key is the number z such that - - z = (y')^x mod p, - -where y' is the other party's public value, x is the private value, -and p is the prime in params. - -The other party's private value y' should be between 0 and p-1. - -agreedKey will be represented most significant byte first, with no -leading zero bytes. agreedKey will have the same length as the prime. - -Return value: 0 success - RE_DATA other party's private value out of range - - -7. VERSION 1.0 ROUTINES - -The following procedures are retained for backward compatibility with -RSAREF 1.0: R_SignPEMBlock, R_SignBlock, R_VerifyPEMSignature, -R_VerifyBlockSignature, R_SealPEMBlock, R_OpenPEMBlock, and -R_DigestBlock. - -The procedures are typically called by message-processing -applications. R_SignBlock is also typically called by key-generation -applications when constructing a PEM or PKCS certification request, -and by certification applications when signing a certificate. -R_DigestBlock has no particular PEM application, but may be useful in -PKCS #7. - -To sign a message, an application calls R_SignPEMBlock, giving these -arguments: - - - a pointer to the message content, and the message length - - an integer identifying which message-digest algorithm to apply - (see Appendix D) - - a flag indicating whether to encode the message in printable - ASCII according to RFC 1421 - - the signer's RSA private key - -R_SignPEMBlock signs the message with the signer's private key and -the specified message-digest algorithm, and optionally encodes the -message in printable ASCII. It returns the signature and possibly the -encoded message. The signature is encoded according to RFC 1421. - -To sign a block of data such as a certificate where the signature is -not encoded in printable ASCII, an application calls R_SignBlock, -giving these arguments: - - - a pointer to the block, and the block length - - an integer identifying which message-digest algorithm to apply - (see Appendix D) - - the signer's RSA private key - -R_SignBlock signs the message with the signer's private key and the -specified message-digest algorithm. It returns the signature. - -To verify a signature on a message, an application calls -R_VerifyPEMSignature, giving these arguments: - - - a pointer to the (possibly encoded) message, and the message - length - - a pointer to the signature, and the signature length - - an integer identifying which message-digest algorithm was applied - (see Appendix D) - - a flag indicating whether the message was encoded in printable - ASCII - - the signer's RSA public key - -R_VerifyPEMSignature decodes the message if it was encoded and -verifies the signature on the message with the signer's public key -and the specified message-digest algorithm. It returns the message -content if the message was encoded. - -To verify a signature on a block of data such as a certificate where -the signature is not encoded in printable ASCII, an application calls -R_VerifyBlockSignature, giving these arguments: - - - a pointer to the block, and the block length - - a pointer to the signature, and the signature length - - an integer identifying which message-digest algorithm was applied - (see Appendix D) - - the signer's RSA public key - -R_VerifyBlockSignature verifies the signature on the message with the -signer's public key and the specified message-digest algorithm. - -To sign and encrypt a message, an application calls R_SealPEMBlock, -giving these arguments: - - - a pointer to the message content, and the message length - - an integer identifying which message-digest algorithm to apply - (see Appendix D) - - the signer's RSA private key - - the recipient's RSA public key - - a random structure - -R_SealPEMBlock signs the message with the signer's private key and -the specified message-digest algorithm, encrypts the message and the -signature with a random DES key, and encrypts the DES key with the -recipient's public key. It returns the encrypted message, the -encrypted key, the encrypted signature, and the DES initialization -vector. The encrypted message, key, and signature are encoded -according to RFC 1421. - -To open a message (decrypt it and verify its signature), an -application calls R_OpenPEMBlock, giving these arguments: - - - a pointer to the encrypted message, and the encrypted message - length - - a pointer to the encrypted key, and the encrypted key length - - a pointer to the encrypted signature, and the encrypted signature - length - - a DES initialization vector - - an integer identifying which message-digest algorithm was applied - (see Appendix D) - - the signer's RSA public key - - the recipient's RSA private key - -R_OpenPEMBlock decrypts the encrypted DES key with the recipient's -private key, decrypts the encrypted message and the encrypted -signature with the DES key, and verifies the signature on the message -with the signer's public key and the specified message-digest -algorithm. It returns the message content. - -To digest a block of data such as a prototype certificate, an -application calls R_DigestBlock, giving these arguments: - - - a pointer to the block, and the block length - - an integer identifying which message-digest algorithm to apply - (see Appendix D) - -R_DigestBlock digests the block with the specified message-digest -algorithm. It returns the message digest. - -ENCODED_CONTENT_LEN, DECODED_CONTENT_LEN, ENCRYPTED_CONTENT_LEN, and -DECRYPTED_CONTENT_LEN are macros that assist in determining the -maximum lengths of the results of cryptographic enhancements. - - -R_SignPEMBlock - -int R_SignPEMBlock ( - unsigned char *encodedContent, /* encoded content */ - unsigned int *encodedContentLen, /* length of encoded content */ - unsigned char *encodedSignature, /* encoded signature */ - unsigned int *encodedSignatureLen, /* length of encoded signature */ - unsigned char *content, /* content */ - unsigned int contentLen, /* length of content */ - int recode, /* recoding flag */ - int digestAlgorithm, /* message-digest algorithm */ - R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ -); - -R_SignPEMBlock computes a digital signature on content. Specifically, -R_SignPEMBlock performs the following steps: - - 1. It digests content with digestAlgorithm, giving a message - digest. - - 2. It encrypts the message digest with privateKey, giving a - digital signature, and encodes the result in printable - ASCII according to RFC 1421, storing the encoding in - encodedSignature. - - 3. If recode is nonzero, it encodes content in printable ASCII, - storing the encoding in encodedContent. - -If recode is nonzero, encodedContent will be an ASCII string, encoded -according to RFC 1421. (It will not contain any line delimiters; the -application must break the string into 64-character lines.) -encodedContentLen will not be greater than -ENCODED_CONTENT_LEN(contentLen). If recode is zero, encodedContent is -ignored. - -encodedSignature will be an ASCII string, encoded according to RFC -1421. encodedSignatureLen will not be greater than -MAX_PEM_SIGNATURE_LEN. - -digestAlgorithm is the algorithm with which the message content is -digested, and must be one of the values listed in Appendix D. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - RE_PRIVATE_KEY privateKey cannot encrypt message digest - - -R_SignBlock - -int R_SignBlock ( - unsigned char *signature, /* encoded signature */ - unsigned int *signatureLen, /* length of encoded signature */ - unsigned char *block, /* block */ - unsigned int blockLen, /* length of block */ - int digestAlgorithm, /* message-digest algorithm */ - R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ -); - -R_SignBlock computes a digital signature on block of data such as a -certificate. Its operation is similar to R_SignPEMBlock, except that -the resulting signature is an arbitrary byte string, rather than an -RFC 1421-encoded string. - -signatureLen will not be greater than MAX_SIGNATURE_LEN. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - RE_PRIVATE_KEY privateKey cannot encrypt message digest - - -R_VerifyPEMSignature - -int R_VerifyPEMSignature ( - unsigned char *content, /* content */ - unsigned int *contentLen, /* length of content */ - unsigned char *encodedContent, /* (possibly) encoded content */ - unsigned int encodedContentLen, /* length of encoded content */ - unsigned char *encodedSignature, /* encoded signature */ - unsigned int encodedSignatureLen, /* length of encoded signature */ - int recode, /* recoding flag */ - int digestAlgorithm, /* message-digest algorithm */ - R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ -); - -R_VerifyPEMSignature verifies a digital signature on a message. Its -operation is the inverse of R_SignPEMBlock. R_VerifyPEMSignature -operates on encodedSignature and encodedContent. If recode is -nonzero, it first decodes encodedContent according to RFC 1421, and -stores the result in content. If recode is zero, content is ignored. - -If recode is nonzero, contentLen will not be greater than -DECODED_CONTENT_LEN(encodedContentLen). - -Return value: 0 success - RE_CONTENT_ENCODING encodedContent has RFC 1421 encoding error -RE_SIGNATURE_ENCODING encodedSignature has RFC 1421 encoding error - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - RE_PUBLIC_KEY publicKey cannot decrypt signature - RE_SIGNATURE signature on content is incorrect - - -R_VerifyBlockSignature - -int R_VerifyBlockSignature ( - unsigned char *block, /* block */ - unsigned int blockLen, /* length of block */ - unsigned char *signature, /* signature */ - unsigned int signatureLen, /* length of signature */ - int digestAlgorithm, /* message-digest algorithm */ - R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ -); - -R_VerifyBlockSignature verifies a digital signature on a block of -data such as a certificate. Its operation is similar to -R_VerifyPEMSignature, except that the block and signature are -arbitrary byte strings, rather than RFC 1421-encoded strings. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - RE_PUBLIC_KEY publicKey cannot decrypt signature - RE_SIGNATURE signature on block is incorrect - - -R_SealPEMBlock - -int R_SealPEMBlock ( - unsigned char *encryptedContent, /* encoded, encrypted content */ - unsigned int *encryptedContentLen, - /* length of encoded, encrypted content */ - unsigned char *encryptedKey, /* encoded, encrypted DES key */ - unsigned int *encryptedKeyLen, - /* length of encoded, encrypted DES key */ - unsigned char *encryptedSignature,/* encoded, encrypted signature */ - unsigned int *encryptedSignatureLen, - /* length of encoded, encrypted signature */ - unsigned char iv[8], /* DES initialization vector */ - unsigned char *content, /* content */ - unsigned int contentLen, /* length of content */ - int digestAlgorithm, /* message-digest algorithm */ - R_RSA_PUBLIC_KEY *publicKey, /* recipient's RSA public key */ - R_RSA_PRIVATE_KEY *privateKey, /* signer's RSA private key */ - R_RANDOM_STRUCT *randomStruct /* random structure */ -); - -R_SealPEMBlock computes a digital signature on content then encrypts -the content and the signature. Specifically, R_SealPEMBlock performs -the following steps: - - 1. It digests content with digestAlgorithm, giving a message - digest. - - 2. It encrypts the message digest with privateKey, giving a - digital signature. - - 3. It generates a random DES key and initialization vector, - storing the initialization vector in iv. - - 4. It encrypts content with the DES key and initialization vector - in cipher-block chaining mode, and encodes the result in - printable ASCII according to RFC 1421, storing the encoding - in encryptedContent. - - 5. It encrypts the DES key with publicKey and encodes the - result in printable ASCII, storing the encoding in - encryptedKey. - - 6. It encrypts the digital signature with the DES key and - initialization vector, and encodes the result in printable - ASCII, storing the encoding in encryptedSignature. - -encryptedContent will be an ASCII string, encoded according to RFC -1421. (It will not contain any line delimiters; the application must -break the string into 64-character lines.) encryptedContentLen will -not be greater than ENCRYPTED_CONTENT_LEN(contentLen). - -encryptedKey and encryptedSignature will be ASCII strings, encoded -according to RFC 1421. encryptedKeyLen will not be greater than -MAX_PEM_ENCRYPTED_KEY_LEN. encryptedSignatureLen will not be greater -than MAX_PEM_ENCRYPTED_SIGNATURE_LEN. - -digestAlgorithm is the algorithm with which the message content is -digested, and must be one of the values listed in Appendix D. - -randomStruct must have been seeded. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - RE_PRIVATE_KEY privateKey cannot encrypt message digest - RE_PUBLIC_KEY publicKey cannot encrypt DES key - RE_NEED_RANDOM randomStruct is not seeded - - -R_OpenPEMBlock - -int R_OpenPEMBlock ( - unsigned char *content, /* content */ - unsigned int *contentLen, /* length of content */ - unsigned char *encryptedContent, /* encoded, encrypted content */ - unsigned int encryptedContentLen, - /* length of encoded, encrypted content */ - unsigned char *encryptedKey, /* encoded, encrypted DES key */ - unsigned int encryptedKeyLen, - /* length of encoded, encrypted DES key */ - unsigned char *encryptedSignature,/* encoded, encrypted signature */ - unsigned int encryptedSignatureLen, - /* length of encoded, encrypted signature */ - unsigned char iv[8], /* DES initialization vector */ - int digestAlgorithm, /* message-digest algorithm */ - R_RSA_PRIVATE_KEY *privateKey, /* recipient's RSA private key */ - R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ -); - -R_OpenPEMBlock decrypts an encrypted message and verifies a digital -signature. Its operation is the inverse of R_SealPEMBlock. - -contentLen will not be greater than -DECRYPTED_CONTENT_LEN(encryptedContentLen). - -Return value: 0 success - RE_CONTENT_ENCODING encryptedContent has RFC 1421 encoding error - RE_KEY_ENCODING encryptedKey has RFC 1421 encoding error -RE_SIGNATURE_ENCODING encryptedSignature has RFC 1421 encoding - error - RE_PUBLIC_KEY publicKey cannot decrypt signature - RE_PRIVATE_KEY privateKey cannot decrypt encrypted key - RE_KEY recovered DES key cannot decrypt encrypted - content or encrypted signature - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - RE_SIGNATURE signature on content is incorrect - - -R_DigestBlock - -int R_DigestBlock ( - unsigned char *digest, /* message digest */ - unsigned int *digestLen, /* length of message digest */ - unsigned char *content, /* content */ - unsigned int contentLen, /* length of content */ - int digestAlgorithm /* message-digest algorithm */ -); - -R_DigestBlock computes the message digest of content, storing the -resulting message digest in digest and its length in bytes in -digestLen. - -digestAlgorithm is the algorithm with which the content is digested, -and must be one of the values in Appendix D. - -digestLen will not be greater than MAX_DIGEST_LEN. - -Return value: 0 success - RE_DIGEST_ALGORITHM digestAlgorithm is invalid - - -8. RUN-TIME LIBRARY - -RSAREF operates on memory blocks with three platform-specific library -procedures that are modeled after conventional C library functions: - - R_memcmp compares two blocks of memory - R_memcpy copies a block of memory - R_memset sets a block of memory to a given value - -These procedures can be found in the file 'r_stdlib.c'. - - -R_memcmp - -int R_memcmp ( - POINTER firstBlock, /* first block */ - POINTER secondBlock, /* second block */ - unsigned int len /* length of blocks */ -); - -R_memcmp compares the first len bytes of firstBlock and secondBlock. -The value of len can be zero, in which case firstBlock and secondBlock -are undefined and R_memcmp returns 0. R_memcmp compares the blocks by -scanning the blocks from lowest address to highest until a difference -is found. The smaller-valued block is the one with the smaller-valued -byte at the point of difference. If no difference is found, the -blocks are equal. - -Return value: < 0 firstBlock is smaller - 0 blocks are equal - > 0 firstBlock is larger - - -R_memcpy - -void R_memcpy ( - POINTER output, /* output block */ - POINTER input, /* input block */ - unsigned int len /* length of blocks */ -); - -R_memcpy copies the first len bytes of input to output. The value of -len can be zero, in which output and input are undefined. The blocks -do not overlap. - -No return value. - - -R_memset - -void R_memset ( - POINTER output, /* output block */ - int value, /* value */ - unsigned int len /* length of block */ -); - -R_memset sets the first len bytes of output to value. The value of -len is zero, in which case output is undefined. - -No return value. - - -APPENDIX A: RSAREF ERROR TYPES - -This appendix lists RSAREF's error types. - - RE_DATA other party's private value out of range - - RE_CONTENT_ENCODING content, encrypted content, or encoded block - has RFC 1421 encoding error - - RE_DIGEST_ALGORITHM message-digest algorithm is invalid - - RE_ENCODING encoded block has RFC 1421 encoding error - -RE_ENCRYPTION_ALGORITHM encryption algorithm is invalid - - RE_KEY recovered DES key cannot decrypt encrypted - content or encrypted signature - - RE_KEY_ENCODING encrypted key has RFC 1421 encoding error - - RE_LEN encrypted key length or signature length - out of range - - RE_MODULUS_LEN modulus length out of range - - RE_NEED_RANDOM random structure is not seeded - - RE_PRIVATE_KEY private key cannot encrypt message digest, - or cannot decrypt encrypted key - - RE_PUBLIC_KEY public key cannot encrypt data encryption - key, or cannot decrypt signature - - RE_SIGNATURE signature on content or block is incorrect - -RE_SIGNATURE_ENCODING signature or encrypted signature has RFC 1421 - encoding error - - -APPENDIX B: RSAREF TYPES - -This appendix lists four RSAREF types: R_RSA_PUBLIC_KEY, -R_RSA_PRIVATE_KEY, R_RSA_PROTO_KEY, and R_DH_PARAMS. - - -R_RSA_PUBLIC_KEY - -typedef struct { - unsigned int bits; /* length in bits of modulus */ - unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ - unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ -} R_RSA_PUBLIC_KEY; - -An R_RSA_PUBLIC_KEY value is a structure specifying an RSA public key. -There are three fields: - - bits length in bits of the modulus (not less than - MIN_RSA_MODULUS_BITS and not greater than - MAX_RSA_MODULUS_BITS) - - modulus modulus n, represented as a - MAX_RSA_MODULUS_LEN-byte number, most - significant byte first, as many leading zero - bytes as necessary - - exponent public exponent e, represented like modulus - - -R_RSA_PRIVATE_KEY - -typedef struct { - unsigned int bits; /* length in bits of modulus */ - unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ - unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; - /* public exponent */ - unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ - unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ - unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; - /* exponents for CRT */ - unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */ -} R_RSA_PRIVATE_KEY; - -An R_RSA_PRIVATE_KEY value is a structure specifying an RSA private -key. There are seven fields: - - bits length in bits of the modulus (not less than - MIN_RSA_MODULUS_BITS and not greater than - MAX_RSA_MODULUS_BITS) - - modulus modulus n, represented as a - MAX_RSA_MODULUS_LEN-byte number, most - significant byte first, as many leading zero - bytes as necessary - - publicExponent public exponent e, represented like modulus - - exponent private exponent d, represented like modulus - - prime prime factors p and q of modulus, each - represented as MAX_RSA_PRIME_LEN-byte - numbers, most significant byte first, as - many leading zero bytes as necessary, where - p > q - - primeExponents exponents (d mod p-1) and (d mod q-1) for - Chinese remainder theorem (CRT) operations, - each represented like prime factors - - coefficient coefficient (q^{-1} mod p) for Chinese - remainder theorem operations, represented - like prime factors - - -R_RSA_PROTO_KEY - -typedef struct { - unsigned int bits; /* length in bits of modulus */ - int useFermat4; /* public exponent (1 = F4, 0 = 3) */ -} R_RSA_PROTO_KEY; - -An R_RSA_PROTO_KEY value is a structure specifying the length in bits -of the RSA modulus and the public exponent for key-pair generation. -There are two fields: - - bits length in bits of the modulus (not less than - MIN_RSA_MODULUS_BITS and not greater than - MAX_RSA_MODULUS_BITS) - - useFermat4 a flag specifying the public exponent. If - nonzero, it specifies F4 (65537); if 0, F0 - (3) - - -R_DH_PARAMS - -typedef struct { - unsigned char *prime; /* prime */ - unsigned int primeLen; /* length of prime */ - unsigned char *generator; /* generator */ - unsigned int generatorLen; /* length of generator */ -} R_DH_PARAMS; - -An R_DH_PARAMS value is a structure specifying Diffie-Hellman -parameters. There are four fields: - - prime prime p, represented as a primeLen-byte - number, most significant byte first, as - many leading zero bytes as necessary - - primeLen length in bytes of the prime - - generator generator g, represented like prime - - generatorLen length in bytes of the generator - - -APPENDIX C: PLATFORM-SPECIFIC TYPES AND CONSTANTS - -This appendix lists three platform-specific types and one #define'd -constant. - - -TYPES - -RSAREF requires three platform-specific types: POINTER, UINT2, and -UINT4. These are defined in the file 'global.h'. - - -POINTER - -A POINTER value is a generic pointer to memory to which any other -pointer can be cast. - -Example: - - typedef unsigned char *POINTER; - - -UINT2 - -A UINT2 value is a 16-bit unsigned integer. - -Example: - - typedef unsigned short int UINT2; - - -UINT4 - -A UINT4 value is a 32-bit unsigned integer. - -Example: - - typedef unsigned long int UINT4; - - -#DEFINE'D CONSTANTS - -RSAREF requires one #define'd constant: PROTOTYPES. This is defined -in the 'makefile' on the C compiler command line. - -PROTOTYPES indicates the form that C function declarations are to -take. If PROTOTYPES is nonzero, declarations take the form - - type function (type, ..., type); - -Otherwise declarations take the form - - type function (); - - -APPENDIX D: ENCRYPTION ALGORITHMS AND IDENTIFIERS - -This appendix lists message-digest and data encryption algorithms and -their identifiers. - - -D.1 Message-digest algorithms - -RSAREF supports two message-digest algorithms, listed here with their -integer identifiers: - - DA_MD2 MD2 message-digest algorithm [3] - - DA_MD5 MD5 message-digest algorithm [4] - - -D.2 Data encryption algorithms - -RSAREF supports four data encryption algorithms, listed here with -their integer identifiers: - - EA_DES_CBC Data Encryption Standard [5] in cipher-block - chaining (CBC) mode [6] - - EA_DESX_CBC RSA Data Security's DESX enhancement of DES, - in CBC mode (this algorithm exclusive-ors - with the previous ciphertext block, - exclusive-ors with a secret value, encrypts - with DES, then exclusive-ors with a second - secret value) - - EA_DES_EDE3_CBC Three-key triple-DES in CBC mode (this - algorithm exclusive-ORs with the previous - ciphertext block, encrypts with one DES - key, decrypts with a second DES key, then - encrypts with a third DES key) - - EA_DES_EDE2_CBC Two-key triple-DES in CBC mode (like three- - key, except that the first and third DES - keys are the same) - -All four algorithms have a block size of eight bytes, and hence an -eight-byte initialization vector. All employ the padding rules -described in RFC 1423 [11]. - - -REFERENCES - -[1] R.L. Rivest, A. Shamir, and L. Adleman. A method for obtaining - digital signatures and public-key cryptosystems. Communications - of the ACM, 21(2):120-126, February 1978. - -[2] RSA Laboratories. PKCS #1: RSA Encryption Standard. Version 1.5, - November 1993. (PKCS documents are available via electronic mail - to .) - -[3] B. Kaliski. RFC 1319: The MD2 Message-Digest Algorithm. April - 1992. - -[4] R. Rivest. RFC 1321: The MD5 Message-Digest Algorithm. April - 1992. - -[5] National Bureau of Standards. FIPS Publication 46-1: Data - Encryption Standard. January 1988. - -[6] National Bureau of Standards. FIPS Publication 81: DES Modes of - Operation. December 1980. - -[7] W. Diffie and M.E. Hellman. New directions in cryptography. IEEE - Transactions on Information Theory, IT-22:644-654, 1976. - -[8] RSA Laboratories. PKCS #3: Diffie-Hellman Key-Agreement Standard. - Version 1.4, November 1993. - -[9] J. Linn. RFC 1421: Privacy Enhancement for Internet Electronic - Mail: Part I: Message Encryption and Authentication Procedures. - February 1993. - -[10] S. Kent. RFC 1422: Privacy Enhancement for Internet Electronic - Mail: Part II: Certificate-Based Key Management. February 1993. - -[11] D. Balenson. RFC 1423: Privacy Enhancement for Internet - Electronic Mail: Part III: Algorithms, Modes, and Identifiers. - February 1993. - -[12] B. Kaliski. RFC 1424: Privacy Enhancement for Internet Electronic - Mail: Part IV: Key Certification and Related Services. February - 1993. - -[13] RSA Laboratories. PKCS #7: Cryptographic Message Syntax Standard. - Version 1.5, November 1993. - -[14] RSA Laboratories. PKCS #10: Certification Request Syntax - Standard. Version 1.0, November 1993. + RSAREF(TM): + A Cryptographic Toolkit for Privacy-Enhanced Mail + Library Reference Manual + + RSA Laboratories + March 2, 1992 + + Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data + Security, Inc. All rights reserved. + + +INTRODUCTION + +This manual is a reference guide for users of RSAREF, a cryptographic +toolkit designed to facilitate rapid development of Internet +Privacy-Enhanced Mail (PEM) [1-3] implementations. + +RSAREF supports the following PEM-specified algorithms: + + - RSA encryption and key generation, as defined by RSA Data + Security's Public-Key Cryptography Standards (PKCS) [4] + - MD2 and MD5 message digests [3,5,6] + - DES (Data Encryption Standard) in cipher-block chaining mode + [7,8] + +RSAREF is written entirely in C. Its application interface includes +the following routines: + + R_SignPEMBlock computes a digital signature on a message +R_VerifyPEMSignature verifies a digital signature on a message +R_VerifyBlockSignature verifies a digital signature on a block of + data such as a certificate + + R_SealPEMBlock computes a digital signature and encrypts a + message + R_OpenPEMBlock decrypts an encrypted message and verifies a + digital signature + + R_DigestBlock computes a message digest on a message + + R_GeneratePEMKeys generates an RSA public/private key pair + + R_RandomInit initializes a random structure + R_RandomUpdate mixes bytes into a random structure +R_GetRandomBytesNeeded computes the number of mix-in bytes still + needed to seed a random structure + R_RandomFinal zeroizes a random structure + +A simple PEM implementation can be built directly on top of these +routines, together with message parsing and formatting routines and +certificate-management routines. + +This manual is divided into five main parts and three appendices. + +This part introduces RSAREF. The next three parts explain RSAREF +procedures: random structures; cryptographic enhancements; and +key-pair generation. The last part documents the platform-specific +run-time library. + +Appendix A lists RSAREF error types. Appendix B lists RSAREF types +and constants. Appendix C lists platform-specific types and +constants. + +RSAREF is intended to be compatible with forthcoming revised versions +of the PEM RFCs, which are now in the unofficial "Internet-Draft" +stage. + + +RANDOM STRUCTURES + +A random structure contains a seed from which a pseudorandom sequence +of bytes is derived. RSAREF generates keys and pads RSA encryption +blocks with bytes derived from a random structure. + +Random structures are used by both message-processing and +key-generation applications. + +RSAREF initializes a random structure with the procedure +R_RandomInit. A typical application calls R_RandomInit on entry. + +A new random structure is not ready for use until it is seeded by +mixing in some random bytes. RSAREF seeds a random structure with the +procedure R_RandomUpdate and R_GetRandomBytesNeeded. A random +structure is considered seeded when the number of bytes still needed +reaches zero. More bytes can be mixed in after the random structure +is seeded. A typical application calls R_GetRandomBytesNeeded and +R_RandomUpdate immediately after calling R_RandomInit. + +RSAREF zeroizes a random structure with the procedure R_RandomFinal. +A typical application calls R_RandomFinal on exit. + + +R_RandomInit + +int R_RandomInit ( + R_RANDOM_STRUCT *randomStruct /* new random structure */ +); + +R_RandomInit initializes a new random structure, storing the result +in randomStruct. + +Return value: 0 success + nonzero reserved for future compatibility + + +R_RandomUpdate + +int R_RandomUpdate ( + R_RANDOM_STRUCT *randomStruct, /* random structure */ + unsigned char *block, /* block of values to mix in */ + unsigned int blockLen /* length of block */ +); + +R_RandomUpdate mixes blockLen bytes from block into randomStruct. + +Return value: 0 success + nonzero reserved for future compatibility + + +R_GetRandomBytesNeeded + +int R_GetRandomBytesNeeded ( + unsigned int *bytesNeeded, /* number of mix-in bytes needed */ + R_RANDOM_STRUCT *randomStruct /* random structure */ +); + +R_GetRandomBytesNeeded computes the number of mix-in bytes still +needed to seed randomStruct, storing the result in bytesNeeded. + +Return value: 0 success + nonzero reserved for future compatibility + + +R_RandomFinal + +void R_RandomFinal ( + R_RANDOM_STRUCT *randomStruct /* random structure */ +); + +R_RandomFinal zeroizes randomStruct. + +No return value. + + +CRYPTOGRAPHIC ENHANCEMENTS + +RSAREF applies cryptographic enhancements to messages with six +procedures: R_SignPEMBlock, R_VerifyPEMSignature, +R_VerifyBlockSignature, R_SealPEMBlock, R_OpenPEMBlock, and +R_DigestBlock. + +The first five procedures are typically called by message-processing +applications. R_DigestBlock is typically called by key-generation +applications when computing the message digest of a prototype +certificate [2,9]. + +To sign a message, an application calls R_SignPEMBlock, giving these +arguments: + + - a pointer to the message content, and the message length + - an integer identifying which message-digest algorithm to apply + (MD2 or MD5) + - a flag indicating whether to encode the message in printable + ASCII according to RFC 1113 + - the signer's RSA private key + +R_SignPEMBlock signs the message with the signer's private key and +the specified message-digest algorithm, and optionally encodes the +message in printable ASCII. It returns the signature, possibly the +encoded message, and the status of the operation. The signature is +encoded according to RFC 1113. + +To verify a signature on a message, an application calls +R_VerifyPEMSignature, giving these arguments: + + - a pointer to the (possibly encoded) message, and the message + length + - a pointer to the signature, and the signature length + - an integer identifying which message-digest algorithm was applied + (MD2 or MD5) + - a flag indicating whether the message was encoded in printable + ASCII + - the signer's RSA public key + +R_VerifyPEMSignature decodes the message if it was encoded and +verifies the signature on the message with the signer's public key +and the specified message-digest algorithm. It returns the message +content if the message was encoded, and the status of the operation. + +To verify a signature on a block of data such as a certificate where +the signature is not encoded in printable ASCII, an application calls +R_VerifyBlockSignature, giving these arguments: + + - a pointer to the block, and the block length + - a pointer to the signature, and the signature length + - an integer identifying which message-digest algorithm was applied + (MD2 or MD5) + - the signer's RSA public key + +R_VerifyBlockSignature verifies the signature on the message with the +signer's public key and the specified message-digest algorithm. It +returns the status of the operation. + +To seal a message (sign and encrypt it), an application calls +R_SealPEMBlock, giving these arguments: + + - a pointer to the message content, and the message length + - an integer identifying which message-digest algorithm to apply + (MD2 or MD5) + - the signer's RSA private key + - the recipient's RSA public key + +R_SealPEMBlock signs the message with the signer's private key and +the specified message-digest algorithm, encrypts the message and the +signature with a random DES key, and encrypts the DES key with the +recipient's public key. It returns the encrypted message, the +encrypted key, the encrypted signature, the DES initialization +vector, and the status of the operation. The encrypted message, key, +and signature are encoded according to RFC 1113. + +To open a message (decrypt it and verify its signature), an +application calls R_OpenPEMBlock, giving these arguments: + + - a pointer to the encrypted message, and the encrypted message + length + - a pointer to the encrypted key, and the encrypted key length + - a pointer to the encrypted signature, and the encrypted signature + length + - a DES initialization vector + - an integer identifying which message-digest algorithm was applied + (MD2 or MD5) + - the signer's RSA public key + - the recipient's RSA private key + +R_OpenPEMBlock decrypts the encrypted DES key with the recipient's +private key, decrypts the encrypted message and the encrypted +signature with the DES key, and verifies the signature on the message +with the signer's public key and the specified message-digest +algorithm. It returns the message content and the status of the +operation. + +To digest a block of data such as a prototype certificate, an +application calls R_DigestBlock, giving these arguments: + + - a pointer to the block, and the block length + - an integer identifying which message-digest algorithm to apply + (MD2 or MD5) + +R_DigestBlock digests the block with the specified message-digest +algorithm. It returns the message digest and the status of the +operation. + +ENCODED_CONTENT_LEN, DECODED_CONTENT_LEN, ENCRYPTED_CONTENT_LEN, and +DECRYPTED_CONTENT_LEN are macros that assist in determining the +maximum lengths of the results of cryptographic enhancements. + + +R_SignPEMBlock + +int R_SignPEMBlock ( + unsigned char *encodedContent, /* encoded content */ + unsigned int *encodedContentLen, /* length of encoded content */ + unsigned char *encodedSignature, /* encoded signature */ + unsigned int *encodedSignatureLen, /* length of encoded signature */ + unsigned char *content, /* content */ + unsigned int contentLen, /* length of content */ + int recode, /* recoding flag */ + int digestAlgorithm, /* message-digest algorithm */ + R_RSA_PRIVATE_KEY *privateKey /* signer's RSA private key */ +); + +R_SignPEMBlock computes a digital signature on content. Specifically, +R_SignPEMBlock performs the following steps: + + 1. It digests content with digestAlgorithm, giving a message + digest. + + 2. It encrypts the message digest with privateKey, giving a + digital signature, and encodes the result in printable + ASCII according to RFC 1113, storing the encoding in + encodedSignature. + + 3. If recode is nonzero, it encodes content in printable ASCII, + storing the encoding in encodedContent. + +If recode is nonzero, encodedContent will be an ASCII string, encoded +according to RFC 1113. (It will not contain any line delimiters; the +application must break the string into 64-character lines.) +encodedContentLen will not be greater than +ENCODED_CONTENT_LEN(contentLen). If recode is zero, encodedContent is +ignored. + +encodedSignature will be an ASCII string, encoded according to RFC +1113. encodedSignatureLen will not be greater than +MAX_PEM_SIGNATURE_LEN. + +digestAlgorithm is the algorithm by which the content is digested. It +must be DA_MD2, which indicates the MD2 message-digest algorithm, or +DA_MD5, which indicates the MD5 message-digest algorithm. + +Return value: 0 success + RE_DIGEST_ALGORITHM digestAlgorithm is invalid + RE_PRIVATE_KEY privateKey cannot encrypt message digest + + +R_VerifyPEMSignature + +int R_VerifyPEMSignature ( + unsigned char *content, /* content */ + unsigned int *contentLen, /* length of content */ + unsigned char *encodedContent, /* (possibly) encoded content */ + unsigned int encodedContentLen, /* length of encoded content */ + unsigned char *encodedSignature, /* encoded signature */ + unsigned int encodedSignatureLen, /* length of encoded signature */ + int recode, /* recoding flag */ + int digestAlgorithm, /* message-digest algorithm */ + R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ +); + +R_VerifyPEMSignature verifies a digital signature on a message. Its +operation is the inverse of R_SignPEMBlock. R_VerifyPEMSignature +operates on encodedSignature and encodedContent. If recode is +nonzero, it first decodes encodedContent according to RFC 1113, and +stores the result in content. If recode is zero, content is ignored. + +If recode is nonzero, contentLen will not be greater than +DECODED_CONTENT_LEN(encodedContentLen). + +Return value: 0 success + RE_CONTENT_ENCODING encodedContent has RFC 1113 encoding error +RE_SIGNATURE_ENCODING encodedSignature has RFC 1113 encoding error + RE_DIGEST_ALGORITHM digestAlgorithm is invalid + RE_PUBLIC_KEY publicKey cannot decrypt signature + RE_SIGNATURE signature on content is incorrect + + +R_VerifyBlockSignature + +int R_VerifyBlockSignature ( + unsigned char *block, /* block */ + unsigned int blockLen, /* length of block */ + unsigned char *signature, /* signature */ + unsigned int signatureLen, /* length of signature */ + int digestAlgorithm, /* message-digest algorithm */ + R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ +); + +R_VerifyBlockSignature verifies a digital signature on a block of +data such as a certificate. Its operation is similar to +R_VerifyPEMSignature, except that the block and signature are +arbitrary byte strings, rather than RFC 1113-encoded strings. + +Return value: 0 success + RE_DIGEST_ALGORITHM digestAlgorithm is invalid + RE_PUBLIC_KEY publicKey cannot decrypt signature + RE_SIGNATURE signature on block is incorrect + + +R_SealPEMBlock + +int R_SealPEMBlock ( + unsigned char *encryptedContent, /* encoded, encrypted content */ + unsigned int *encryptedContentLen, + /* length of encoded, encrypted content */ + unsigned char *encryptedKey, /* encoded, encrypted DES key */ + unsigned int *encryptedKeyLen, + /* length of encoded, encrypted DES key */ + unsigned char *encryptedSignature,/* encoded, encrypted signature */ + unsigned int *encryptedSignatureLen, + /* length of encoded, encrypted signature */ + unsigned char iv[8], /* DES initializing vector */ + unsigned char *content, /* content */ + unsigned int contentLen, /* length of content */ + int digestAlgorithm, /* message-digest algorithm */ + R_RSA_PUBLIC_KEY *publicKey, /* recipient's RSA public key */ + R_RSA_PRIVATE_KEY *privateKey, /* signer's RSA private key */ + R_RANDOM_STRUCT *randomStruct /* random structure */ +); + +R_SealPEMBlock computes a digital signature on content then encrypts +the content and the signature. Specifically, R_SealPEMBlock performs +the following steps: + + 1. It digests content with digestAlgorithm, giving a message + digest. + + 2. It encrypts the message digest with privateKey, giving a + digital signature. + + 3. It generates a random DES key and initializing vector, + storing the initializing vector in iv. + + 4. It encrypts content with the DES key and initializing vector + in cipher-block chaining mode, and encodes the result in + printable ASCII according to RFC 1113, storing the encoding + in encryptedContent. + + 5. It encrypts the DES key with publicKey and encodes the + result in printable ASCII, storing the encoding in + encryptedKey. + + 6. It encrypts the digital signature with the DES key and + initializing vector, and encodes the result in printable + ASCII, storing the encoding in encryptedSignature. + +encryptedContent will be an ASCII string, encoded according to RFC +1113. (It will not contain any line delimiters; the application must +break the string into 64-character lines.) encryptedContentLen will +not be greater than ENCRYPTED_CONTENT_LEN(contentLen). + +encryptedKey and encryptedSignature will be ASCII strings, encoded +according to RFC 1113. encryptedKeyLen will not be greater than +MAX_PEM_ENCRYPTED_KEY_LEN. encryptedSignatureLen will not be greater +than MAX_PEM_ENCRYPTED_SIGNATURE_LEN. + +digestAlgorithm is the algorithm by which the content is digested. It +must be DA_MD2, which indicates the MD2 message-digest algorithm, or +DA_MD5, which indicates the MD5 message-digest algorithm. + +randomStruct must have been seeded. + +Return value: 0 success + RE_DIGEST_ALGORITHM digestAlgorithm is invalid + RE_PRIVATE_KEY privateKey cannot encrypt message digest + RE_PUBLIC_KEY publicKey cannot encrypt DES key + RE_NEED_RANDOM randomStruct is not seeded + + +R_OpenPEMBlock + +int R_OpenPEMBlock ( + unsigned char *content, /* content */ + unsigned int *contentLen, /* length of content */ + unsigned char *encryptedContent, /* encoded, encrypted content */ + unsigned int encryptedContentLen, + /* length of encoded, encrypted content */ + unsigned char *encryptedKey, /* encoded, encrypted DES key */ + unsigned int encryptedKeyLen, + /* length of encoded, encrypted DES key */ + unsigned char *encryptedSignature,/* encoded, encrypted signature */ + unsigned int encryptedSignatureLen, + /* length of encoded, encrypted signature */ + unsigned char iv[8], /* DES initializing vector */ + int digestAlgorithm, /* message-digest algorithm */ + R_RSA_PRIVATE_KEY *privateKey, /* recipient's RSA private key */ + R_RSA_PUBLIC_KEY *publicKey /* signer's RSA public key */ +); + +R_OpenPEMBlock decrypts an encrypted message and verifies a digital +signature. Its operation is the inverse of R_SealPEMBlock. + +contentLen will not be greater than +DECRYPTED_CONTENT_LEN(encryptedContentLen). + +Return value: 0 success + RE_CONTENT_ENCODING encryptedContent has RFC 1113 encoding error + RE_KEY_ENCODING encryptedKey has RFC 1113 encoding error +RE_SIGNATURE_ENCODING encryptedSignature has RFC 1113 encoding + error + RE_PUBLIC_KEY publicKey cannot decrypt signature + RE_PRIVATE_KEY privateKey cannot decrypt encrypted key + RE_KEY recovered DES key cannot decrypt encrypted + content or encrypted signature + RE_DIGEST_ALGORITHM digestAlgorithm is invalid + RE_SIGNATURE signature on content is incorrect + + +R_DigestBlock + +int R_DigestBlock ( + unsigned char *digest, /* message digest */ + unsigned int *digestLen, /* length of message digest */ + unsigned char *content, /* content */ + unsigned int contentLen, /* length of content */ + int digestAlgorithm /* message-digest algorithm */ +); + +R_DigestBlock computes a message digest on content, storing the +resulting message digest in digest and its length in digestLen. + +digestAlgorithm is the algorithm by which the content is digested. It +must be DA_MD2, which indicates the MD2 message-digest algorithm, or +DA_MD5, which indicates the MD5 message-digest algorithm. + +digestLen will not be greater than MAX_DIGEST_LEN. + +Return value: 0 success + RE_DIGEST_ALGORITHM digestAlgorithm is invalid + + +KEY-PAIR GENERATION + +RSAREF generates key pairs with the procedure R_GeneratePEMKeys. +R_GeneratePEMKeys is typically called by key generation applications. +To generate a new key pair, an application calls R_GeneratePEMKeys, +giving the length of the modulus, the choice of exponent (F4 or F0), +and a random structure. R_GeneratePEMKeys generates an RSA key pair +and returns the status of the operation. + + +R_GeneratePEMKeys + +int R_GeneratePEMKeys ( + R_RSA_PUBLIC_KEY *publicKey, /* new RSA public key */ + R_RSA_PRIVATE_KEY *privateKey, /* new RSA private key */ + R_RSA_PROTO_KEY *protoKey, /* RSA prototype key */ + R_RANDOM_STRUCT *randomStruct /* random structure */ +); + +R_GeneratePEMKeys generates a random RSA key pair, storing the +resulting RSA public key in publicKey and the resulting RSA private +key in privateKey. + +Other parameters are as follows: + + protoKey The RSA prototype key specifying the length + in bits of the RSA modulus and the public + exponent. (See Appendix B.) + + randomStruct Random structure from which the key pair is + derived. It must have been seeded. + +Return value: 0 success + RE_MODULUS_LEN modulus length invalid + RE_NEED_RANDOM randomStruct is not seeded + + +RUN-TIME LIBRARY + +RSAREF operates on memory blocks with three platform-specific library +procedures that are modeled after conventional C library functions: + + R_memcmp compares two blocks of memory + R_memcpy copies a block of memory + R_memset sets a block of memory to a given value + +These procedures can be found in the file 'r_stdlib.c'. + + +R_memcmp + +int R_memcmp ( + POINTER firstBlock, /* first block */ + POINTER secondBlock, /* second block */ + unsigned int len /* length of blocks */ +); + +R_memcmp compares the first len bytes of firstBlock and secondBlock. +The value of len can be zero, in which case firstBlock and secondBlock +are undefined and R_memcmp returns 0. R_memcmp compares the blocks by +scanning the blocks from lowest address to highest until a difference +is found. The smaller-valued block is the one with the smaller-valued +byte at the point of difference. If no difference is found, the +blocks are equal. + +Return value: < 0 firstBlock is smaller + 0 blocks are equal + > 0 firstBlock is larger + + +R_memcpy + +void R_memcpy ( + POINTER output, /* output block */ + POINTER input, /* input block */ + unsigned int len /* length of blocks */ +); + +R_memcpy copies the first len bytes of input to output. The value of +len can be zero, in which output and input are undefined. The blocks +do not overlap. + +No return value. + + +R_memset + +void R_memset ( + POINTER output, /* output block */ + int value, /* value */ + unsigned int len /* length of block */ +); + +R_memset sets the first len bytes of output to value. The value of +len is zero, in which case output is undefined. + +No return value. + + +APPENDIX A: RSAREF ERROR TYPES + +This appendix lists RSAREF's error types. + + RE_CONTENT_ENCODING content or encrypted content has RFC 1113 + encoding error + + RE_DIGEST_ALGORITHM message-digest algorithm is invalid + + RE_KEY recovered DES key cannot decrypt encrypted + content or encrypted signature + + RE_KEY_ENCODING encrypted key has RFC 1113 encoding error + + RE_MODULUS_LEN modulus length is invalid + + RE_NEED_RANDOM random structure is not seeded + + RE_PRIVATE_KEY private key cannot encrypt message digest, + or cannot decrypt encrypted key + + RE_PUBLIC_KEY public key cannot encrypt DES key, or cannot + decrypt signature + + RE_SIGNATURE signature on content or block is incorrect + +RE_SIGNATURE_ENCODING signature or encrypted signature has RFC 1113 + encoding error + + +APPENDIX B: RSAREF TYPES + +This appendix lists three RSAREF types: R_RSA_PUBLIC_KEY, +R_RSA_PRIVATE_KEY, and R_RSA_PROTO_KEY. + + +R_RSA_PUBLIC_KEY + +typedef struct { + unsigned int bits; /* length in bits of modulus */ + unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ + unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */ +} R_RSA_PUBLIC_KEY; + +An R_RSA_PUBLIC_KEY value is a structure specifying an RSA public key. +There are three fields: + + bits length in bits of the modulus (not less than + MIN_RSA_MODULUS_BITS and not greater than + MAX_RSA_MODULUS_BITS) + + modulus modulus n, represented as a + MAX_RSA_MODULUS_LEN-byte number, most + significant byte first, as many leading zero + bytes as necessary + + exponent public exponent e, represented like modulus + + +R_RSA_PRIVATE_KEY + +typedef struct { + unsigned int bits; /* length in bits of modulus */ + unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */ + unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; + /* public exponent */ + unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */ + unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */ + unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; + /* exponents for CRT */ + unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */ +} R_RSA_PRIVATE_KEY; + +An R_RSA_PRIVATE_KEY value is a structure specifying an RSA private +key. There are seven fields: + + bits length in bits of the modulus (not less than + MIN_RSA_MODULUS_BITS and not greater than + MAX_RSA_MODULUS_BITS) + + modulus modulus n, represented as a + MAX_RSA_MODULUS_LEN-byte number, most + significant byte first, as many leading zero + bytes as necessary + + publicExponent public exponent e, represented like modulus + + exponent private exponent d, represented like modulus + + prime prime factors p and q of modulus, each + represented as MAX_RSA_PRIME_LEN-byte + numbers, most significant byte first, as + many leading zero bytes as necessary, where + p > q + + primeExponents exponents (d mod p-1) and (d mod q-1) for + Chinese remainder theorem (CRT) operations, + each represented like prime factors + + coefficient coefficient (q^{-1} mod p) for Chinese + remainder theorem operations, represented + like prime factors + + +R_RSA_PROTO_KEY + +/* RSA prototype key. + */ +typedef struct { + unsigned int bits; /* length in bits of modulus */ + int useFermat4; /* public exponent (1 = F4, 0 = 3) */ +} R_RSA_PROTO_KEY; + +An R_RSA_PROTO_KEY value is a structure specifying the length in bits +of the RSA modulus and the public exponent for key-pair generation. +There are two fields: + + bits length in bits of the modulus (not less than + MIN_RSA_MODULUS_BITS and not greater than + MAX_RSA_MODULUS_BITS) + + useFermat4 a flag specifying the public exponent. If + nonzero, it specifies F4 (65537); if 0, F0 + (3) + + +APPENDIX C: PLATFORM-SPECIFIC TYPES AND CONSTANTS + +This appendix lists three platform-specific types and one #define'd +constant. + + +TYPES + +RSAREF requires three platform-specific types: POINTER, UINT2, and +UINT4. These are defined in the file 'global.h'. + + +POINTER + +A POINTER value is a generic pointer to memory to which any other +pointer can be cast. + +Example: + + typedef unsigned char *POINTER; + + +UINT2 + +A UINT2 value is a 16-bit unsigned integer. + +Example: + + typedef unsigned short int UINT2; + + +UINT4 + +A UINT4 value is a 32-bit unsigned integer. + +Example: + + typedef unsigned long int UINT4; + + +#DEFINE'D CONSTANTS + +RSAREF requires one #define'd constant: PROTOTYPES. This is defined +in the 'makefile' on the C compiler command line. + +PROTOTYPES indicates the form that C function declarations are to +take. If PROTOTYPES is nonzero, declarations take the form + + type function (type, ..., type); + +Otherwise declarations take the form + + type function (); + + +REFERENCES + +[1] J. Linn. RFC 1113: Privacy Enhancement for Internet Electronic + Mail: Part I -- Message Encipherment and Authentication + Procedures. Internet Activities Board, August 1989. + +[2] S. Kent and J. Linn. RFC 1114: Privacy Enhancement for Internet + Electronic Mail: Part II -- Certificate-Based Key Management. + Internet Activities Board, August 1989. + +[3] J. Linn. RFC 1115: Privacy Enhancement for Internet Electronic + Mail: Part III -- Algorithms, Modes, and Identifiers. Internet + Activities Board, August 1989. + +[4] RSA Data Security, Inc. PKCS #1: RSA Encryption Standard. Version + 1.4, June 1991. Also published as NIST/OSI Implementors Workshop + SEC-SIG-91-18, June 1991. (Available by anonymous FTP from + 'rsa.com' as 'pub/pkcs/pkcs-1.ps'.) + +[5] B.S. Kaliski Jr. The MD2 Message-Digest Algorithm. July 1, 1991. + (Available by anonymous FTP from 'rsa.com' as 'pub/md2.doc'.) + +[6] Ronald L. Rivest. The MD5 Message-Digest Algorithm. In + preparation. (Earlier version available by anonymous FTP from + 'rsa.com' as 'pub/md5.doc'.) + +[7] National Bureau of Standards. FIPS Publication 46-1: Data + Encryption Standard. January 1988. + +[8] National Bureau of Standards. FIPS Publication 81: DES Modes of + Operation. December 1980. + +[9] B.S. Kaliski Jr. Privacy Enhancement for Internet Electronic + Mail: Part IV: Notary, Co-Issuer, CRL-Storing, and + CRL-Retrieving Services. Draft, July 1, 1991. (Available by + anonymous FTP from 'rsa.com' as 'pub/forms.doc'.)