Add PRF preference ctrl to ciphers.
diff --git a/CHANGES b/CHANGES
index f3cc504..a7ea7eb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,7 +6,9 @@
 
   *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
      Reorganize PBE internals to lookup from a static table using NIDs,
-     add support for HMAC PBE OID translation.
+     add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl:
+     EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative
+     PRF which will be automatically used with PBES2.
      [Steve Henson]
 
   *) Replace the algorithm specific calls to generate keys in "req" with the
diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c
index c834a38..ef2684b 100644
--- a/crypto/asn1/p5_pbev2.c
+++ b/crypto/asn1/p5_pbev2.c
@@ -95,6 +95,7 @@
 	PBE2PARAM *pbe2 = NULL;
 	ASN1_OCTET_STRING *osalt = NULL;
 	ASN1_OBJECT *obj;
+	int prf_nid;
 
 	alg_nid = EVP_CIPHER_type(cipher);
 	if(alg_nid == NID_undef) {
@@ -119,7 +120,7 @@
 
 	EVP_CIPHER_CTX_init(&ctx);
 
-	/* Dummy cipherinit to just setup the IV */
+	/* Dummy cipherinit to just setup the IV, and PRF */
 	EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
 	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
 		ASN1err(ASN1_F_PKCS5_PBE2_SET,
@@ -127,6 +128,12 @@
 		EVP_CIPHER_CTX_cleanup(&ctx);
 		goto err;
 	}
+	/* An error is OK here: just means use default PRF */
+	if (EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
+		{
+		ERR_clear_error();
+		prf_nid = NID_hmacWithSHA1;
+		}
 	EVP_CIPHER_CTX_cleanup(&ctx);
 
 	if(!(kdf = PBKDF2PARAM_new())) goto merr;
@@ -154,7 +161,15 @@
 				 EVP_CIPHER_key_length(cipher))) goto merr;
 	}
 
-	/* prf can stay NULL because we are using hmacWithSHA1 */
+	/* prf can stay NULL if we are using hmacWithSHA1 */
+	if (prf_nid != NID_hmacWithSHA1)
+		{
+		kdf->prf = X509_ALGOR_new();
+		if (!kdf->prf)
+			goto merr;
+		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
+					V_ASN1_NULL, NULL);
+		}
 
 	/* Now setup the PBE2PARAM keyfunc structure */
 
diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c
index d37726f..4fd8c41 100644
--- a/crypto/evp/e_rc2.c
+++ b/crypto/evp/e_rc2.c
@@ -223,6 +223,11 @@
 			return 1;
 			}
 		return 0;
+#if PBE_PRF_TEST
+	case EVP_CTRL_PBE_PRF_NID:
+		*(int *)ptr = NID_hmacWithMD5;
+		return 1;
+#endif
 
 	default:
 		return -1;
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index db33634..2622b53 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -301,6 +301,7 @@
 #define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
 #define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
 #define 	EVP_CTRL_RAND_KEY		0x6
+#define 	EVP_CTRL_PBE_PRF_NID		0x7
 
 typedef struct evp_cipher_info_st
 	{