This patch improves the documentation on the PEM ENCRYPTION algorithm.
The improvements attempts to clarify the use of the salt and
initialization vector, and include pseudo-code.

*****

diff --git a/doc/crypto/pem.pod b/doc/crypto/pem.pod
index 21e9fe3..5c8a1e4 100644
--- a/doc/crypto/pem.pod
+++ b/doc/crypto/pem.pod
@@ -444,15 +444,40 @@ The private key (or other data) takes the following form:
  ...base64 encoded data...
  -----END RSA PRIVATE KEY-----

-The line beginning DEK-Info contains two comma separated pieces of information:
-the encryption algorithm name as used by EVP_get_cipherbyname() and an 8
-byte B<salt> encoded as a set of hexadecimal digits.
+The line beginning with Proc-Type contains the version and the
protection on the
+encapsulated data. The line beginning DEK-Info contains two comma separated
+values: the encryption algorithm name as used by EVP_get_cipherbyname() and an
+initialization vector used by the cipher encoded as a set of hexadecimal
+digits. After the Proc-Type and DEK-Info is the base64 encoded encrypted data.

-After this is the base64 encoded encrypted data.
+The encryption key is derived using EVP_BytesToKey(). The cipher's
initialization
+vector is passed to EVP_BytesToKey() as the B<salt> parameter. Internally,
+B<PKCS5_SALT_LEN> bytes of the salt are used (regardless of the size of the
+initialization vector). The user's password is passed to to EVP_BytesToKey()
+using the B<data> and B<datal> parameters. Finally, the library uses
an iteration
+count of 1 for EVP_BytesToKey().

-The encryption key is determined using EVP_BytesToKey(), using B<salt> and an
-iteration count of 1. The IV used is the value of B<salt> and *not* the IV
-returned by EVP_BytesToKey().
+The B<key> derived by EVP_BytesToKey() along with the original initialization
+vector is then used to decrypt the encrypted data. The B<iv> produced by
+EVP_BytesToKey() is not utilized or needed, and NULL should be passed to
+the function.
+
+The pseudo code to derive the key would look similar to:
+
+ EVP_CIPHER* cipher = EVP_des_ede3_cbc();
+ EVP_MD* md = EVP_md5();
+
+ unsigned int nkey = EVP_CIPHER_key_length(cipher);
+ unsigned int niv = EVP_CIPHER_iv_length(cipher);
+
+ unsigned char key[nkey];
+ unsigned char iv[niv];
+ memcpy(iv, HexToBin("3F17F5316E2BAC89"), niv);
+
+ rc = EVP_BytesToKey(cipher, md, iv /*salt*/, pword, plen, 1, key,
NULL /*iv*/);
+ if(rc != nkey) exit(-1);
+
+ /* On success, use key and iv to initialize the cipher */

 =head1 BUGS

diff --git a/doc/crypto/pem.pod b/doc/crypto/pem.pod
index 21e9fe3..5c8a1e4 100644
--- a/doc/crypto/pem.pod
+++ b/doc/crypto/pem.pod
@@ -444,15 +444,40 @@ The private key (or other data) takes the following form:
  ...base64 encoded data...
  -----END RSA PRIVATE KEY-----
 
-The line beginning DEK-Info contains two comma separated pieces of information:
-the encryption algorithm name as used by EVP_get_cipherbyname() and an 8
-byte B<salt> encoded as a set of hexadecimal digits.
+The line beginning with Proc-Type contains the version and the protection on 
the
+encapsulated data. The line beginning DEK-Info contains two comma separated
+values: the encryption algorithm name as used by EVP_get_cipherbyname() and an
+initialization vector used by the cipher encoded as a set of hexadecimal
+digits. After the Proc-Type and DEK-Info is the base64 encoded encrypted data.
 
-After this is the base64 encoded encrypted data.
+The encryption key is derived using EVP_BytesToKey(). The cipher's 
initialization
+vector is passed to EVP_BytesToKey() as the B<salt> parameter. Internally,
+B<PKCS5_SALT_LEN> bytes of the salt are used (regardless of the size of the 
+initialization vector). The user's password is passed to to EVP_BytesToKey()
+using the B<data> and B<datal> parameters. Finally, the library uses an 
iteration
+count of 1 for EVP_BytesToKey().
 
-The encryption key is determined using EVP_BytesToKey(), using B<salt> and an
-iteration count of 1. The IV used is the value of B<salt> and *not* the IV
-returned by EVP_BytesToKey().
+The B<key> derived by EVP_BytesToKey() along with the original initialization
+vector is then used to decrypt the encrypted data. The B<iv> produced by
+EVP_BytesToKey() is not utilized or needed, and NULL should be passed to
+the function.
+
+The pseudo code to derive the key would look similar to:
+
+ EVP_CIPHER* cipher = EVP_des_ede3_cbc();
+ EVP_MD* md = EVP_md5();
+
+ unsigned int nkey = EVP_CIPHER_key_length(cipher);
+ unsigned int niv = EVP_CIPHER_iv_length(cipher);
+
+ unsigned char key[nkey];
+ unsigned char iv[niv];
+ memcpy(iv, HexToBin("3F17F5316E2BAC89"), niv);
+
+ rc = EVP_BytesToKey(cipher, md, iv /*salt*/, pword, plen, 1, key, NULL 
/*iv*/);
+ if(rc != nkey) exit(-1);
+
+ /* On success, use key and iv to initialize the cipher */
 
 =head1 BUGS
 

Reply via email to