Allow dynamic overriding of ROTPK verification

A production ROM with TBB enabled must have the ability to boot test software
before a real ROTPK is deployed (e.g. manufacturing mode). Previously the
function plat_get_rotpk_info() must return a valid ROTPK for TBB to succeed.
This patch adds an additional bit `ROTPK_NOT_DEPLOYED` in the output `flags`
parameter from plat_get_rotpk_info(). If this bit is set, then the ROTPK
in certificate is used without verifying against the platform value.

Fixes ARM-software/tf-issues#381

Change-Id: Icbbffab6bff8ed76b72431ee21337f550d8fdbbb
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 8947def..fba320a 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -631,10 +631,19 @@
         digest            OCTET STRING
     }
 
-The function returns 0 on success. Any other value means the ROTPK could not be
-retrieved from the platform. The function also reports extra information related
-to the ROTPK in the flags parameter.
+The function returns 0 on success. Any other value is treated as error by the
+Trusted Board Boot. The function also reports extra information related
+to the ROTPK in the flags parameter:
 
+    ROTPK_IS_HASH      : Indicates that the ROTPK returned by the platform is a
+                         hash.
+    ROTPK_NOT_DEPLOYED : This allows the platform to skip certificate ROTPK
+                         verification while the platform ROTPK is not deployed.
+                         When this flag is set, the function does not need to
+                         return a platform ROTPK, and the authentication
+                         framework uses the ROTPK in the certificate without
+                         verifying it against the platform value. This flag
+                         must not be used in a deployed production environment.
 
 ### Function: plat_get_nv_ctr()
 
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 4184556..88ef0b0 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -199,8 +199,9 @@
 	}
 	return_if_error(rc);
 
-	/* If the PK is a hash of the key, retrieve the key from the image */
-	if (flags & ROTPK_IS_HASH) {
+	if (flags & (ROTPK_IS_HASH | ROTPK_NOT_DEPLOYED)) {
+		/* If the PK is a hash of the key or if the ROTPK is not
+		   deployed on the platform, retrieve the key from the image */
 		pk_hash_ptr = pk_ptr;
 		pk_hash_len = pk_len;
 		rc = img_parser_get_auth_param(img_desc->img_type,
@@ -215,9 +216,14 @@
 						 pk_ptr, pk_len);
 		return_if_error(rc);
 
-		/* Ask the crypto-module to verify the key hash */
-		rc = crypto_mod_verify_hash(pk_ptr, pk_len,
-					    pk_hash_ptr, pk_hash_len);
+		if (flags & ROTPK_NOT_DEPLOYED) {
+			NOTICE("ROTPK is not deployed on platform. "
+				"Skipping ROTPK verification.\n");
+		} else {
+			/* Ask the crypto-module to verify the key hash */
+			rc = crypto_mod_verify_hash(pk_ptr, pk_len,
+				    pk_hash_ptr, pk_hash_len);
+		}
 	} else {
 		/* Ask the crypto module to verify the signature */
 		rc = crypto_mod_verify_signature(data_ptr, data_len,
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index a08a12e..390721f 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -49,6 +49,9 @@
  * plat_get_rotpk_info() flags
  ******************************************************************************/
 #define ROTPK_IS_HASH			(1 << 0)
+/* Flag used to skip verification of the certificate ROTPK while the platform
+   ROTPK is not deployed */
+#define ROTPK_NOT_DEPLOYED		(1 << 1)
 
 /*******************************************************************************
  * Function declarations