Makefile: Add support to optionally encrypt BL31 and BL32

Following build flags have been added to support optional firmware
encryption:

- FW_ENC_STATUS: Top level firmware's encryption numeric flag, values:
    0: Encryption is done with Secret Symmetric Key (SSK) which is
       common for a class of devices.
    1: Encryption is done with Binding Secret Symmetric Key (BSSK) which
       is unique per device.

- ENC_KEY: A 32-byte (256-bit) symmetric key in hex string format. It
    could be SSK or BSSK depending on FW_ENC_STATUS flag.

- ENC_NONCE: A 12-byte (96-bit) encryption nonce or Initialization Vector
    (IV) in hex string format.

- ENCRYPT_BL31: Binary flag to enable encryption of BL31 firmware.

- ENCRYPT_BL32: Binary flag to enable encryption of Secure BL32 payload.

Similar flags can be added to encrypt other firmwares as well depending
on use-cases.

Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Change-Id: I94374d6830ad5908df557f63823e58383d8ad670
diff --git a/Makefile b/Makefile
index 8f50d7c..3d5b395 100644
--- a/Makefile
+++ b/Makefile
@@ -159,6 +159,14 @@
 endif
 endif
 
+ifneq (${DECRYPTION_SUPPORT},none)
+ENC_ARGS += -f ${FW_ENC_STATUS}
+ENC_ARGS += -k ${ENC_KEY}
+ENC_ARGS += -n ${ENC_NONCE}
+FIP_DEPS += enctool
+FWU_FIP_DEPS += enctool
+endif
+
 ################################################################################
 # Toolchain
 ################################################################################
@@ -826,10 +834,13 @@
 $(eval $(call assert_boolean,BL2_IN_XIP_MEM))
 $(eval $(call assert_boolean,BL2_INV_DCACHE))
 $(eval $(call assert_boolean,USE_SPINLOCK_CAS))
+$(eval $(call assert_boolean,ENCRYPT_BL31))
+$(eval $(call assert_boolean,ENCRYPT_BL32))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
 $(eval $(call assert_numeric,BRANCH_PROTECTION))
+$(eval $(call assert_numeric,FW_ENC_STATUS))
 
 ifdef KEY_SIZE
         $(eval $(call assert_numeric,KEY_SIZE))
@@ -867,6 +878,8 @@
 $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
 $(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
 $(eval $(call add_define,ENABLE_SVE_FOR_NS))
+$(eval $(call add_define,ENCRYPT_BL31))
+$(eval $(call add_define,ENCRYPT_BL32))
 $(eval $(call add_define,ERROR_DEPRECATED))
 $(eval $(call add_define,FAULT_INJECTION_SUPPORT))
 $(eval $(call add_define,GICV2_G0_FOR_EL3))
@@ -987,9 +1000,14 @@
 
 ifeq (${NEED_BL31},yes)
 BL31_SOURCES += ${SPD_SOURCES}
+ifneq (${DECRYPTION_SUPPORT},none)
+$(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw,,$(ENCRYPT_BL31))),\
+	$(eval $(call MAKE_BL,31,soc-fw,,$(ENCRYPT_BL31))))
+else
 $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw)),\
 	$(eval $(call MAKE_BL,31,soc-fw)))
 endif
+endif
 
 # If a BL32 image is needed but neither BL32 nor BL32_SOURCES is defined, the
 # build system will call TOOL_ADD_IMG to print a warning message and abort the
@@ -998,9 +1016,14 @@
 
 BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1))
 
+ifneq (${DECRYPTION_SUPPORT},none)
+$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw,,$(ENCRYPT_BL32))),\
+	$(eval $(call TOOL_ADD_IMG,bl32,--tos-fw,,$(ENCRYPT_BL32))))
+else
 $(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw)),\
 	$(eval $(call TOOL_ADD_IMG,bl32,--tos-fw)))
 endif
+endif
 
 # Add the BL33 image if required by the platform
 ifeq (${NEED_BL33},yes)
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 032e42c..20a36fe 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -109,6 +109,22 @@
     ${BUILD_PLAT}/bl$(1).bin
 endef
 
+# IMG_ENC_BIN defines the default encrypted image file corresponding to a
+# BL stage
+#   $(1) = BL stage (2, 30, 31, 32, 33)
+define IMG_ENC_BIN
+    ${BUILD_PLAT}/bl$(1)_enc.bin
+endef
+
+# ENCRYPT_FW invokes enctool to encrypt firmware binary
+#   $(1) = input firmware binary
+#   $(2) = output encrypted firmware binary
+define ENCRYPT_FW
+$(2): $(1) enctool
+	$$(ECHO) "  ENC     $$<"
+	$$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+endef
+
 # TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
 # package a new payload and/or by cert_create to generate certificate.
 # Optionally, it adds the dependency on this payload
@@ -116,11 +132,17 @@
 #   $(2) = command line option for the specified payload (i.e. --soc-fw)
 #   $(3) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
 #   $(4) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+#   $(5) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
 define TOOL_ADD_PAYLOAD
+ifneq ($(5),)
+    $(4)FIP_ARGS += $(2) $(5)
+    $(if $(3),$(4)CRT_DEPS += $(1))
+else
     $(4)FIP_ARGS += $(2) $(1)
+    $(if $(3),$(4)CRT_DEPS += $(3))
+endif
     $(if $(3),$(4)FIP_DEPS += $(3))
     $(4)CRT_ARGS += $(2) $(1)
-    $(if $(3),$(4)CRT_DEPS += $(3))
 endef
 
 # TOOL_ADD_IMG_PAYLOAD works like TOOL_ADD_PAYLOAD, but applies image filters
@@ -130,6 +152,7 @@
 #   $(3) = command line option for the specified payload (ex. --soc-fw)
 #   $(4) = tool target dependency (optional) (ex. build/fvp/release/bl31.bin)
 #   $(5) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+#   $(6) = encrypted payload (optional) (ex. build/fvp/release/bl31_enc.bin)
 
 define TOOL_ADD_IMG_PAYLOAD
 
@@ -143,10 +166,10 @@
 
 $(PROCESSED_PATH): $(4)
 
-$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5))
+$(call TOOL_ADD_PAYLOAD,$(PROCESSED_PATH),$(3),$(PROCESSED_PATH),$(5),$(6))
 
 else
-$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5))
+$(call TOOL_ADD_PAYLOAD,$(2),$(3),$(4),$(5),$(6))
 endif
 endef
 
@@ -164,6 +187,7 @@
 #   $(1) = image_type (scp_bl2, bl33, etc.)
 #   $(2) = command line option for fiptool (--scp-fw, --nt-fw, etc)
 #   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+#   $(4) = Image encryption flag (optional) (0, 1)
 # Example:
 #   $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw))
 define TOOL_ADD_IMG
@@ -173,7 +197,14 @@
 
     $(3)CRT_DEPS += check_$(1)
     $(3)FIP_DEPS += check_$(1)
+ifeq ($(4),1)
+    $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin)
+    $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN))
+    $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
+		$(ENC_BIN))
+else
     $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),,$(3))
+endif
 
 .PHONY: check_$(1)
 check_$(1):
@@ -390,6 +421,7 @@
 #   $(1) = BL stage (1, 2, 2u, 31, 32)
 #   $(2) = FIP command line option (if empty, image will not be included in the FIP)
 #   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
+#   $(4) = BL encryption flag (optional) (0, 1)
 define MAKE_BL
         $(eval BUILD_DIR  := ${BUILD_PLAT}/bl$(1))
         $(eval BL_SOURCES := $(BL$(call uppercase,$(1))_SOURCES))
@@ -400,6 +432,7 @@
         $(eval ELF        := $(call IMG_ELF,$(1)))
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
+        $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
         $(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
         $(eval BL_LIBS    := $(BL$(call uppercase,$(1))_LIBS))
         # We use sort only to get a list of unique object directory names.
@@ -480,7 +513,13 @@
 
 all: bl$(1)
 
+ifeq ($(4),1)
+$(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
+		$(ENC_BIN)))
+else
 $(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(BIN),$(3)))
+endif
 
 endef
 
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 0127607..03322db 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -109,6 +109,18 @@
 # Use BRANCH_PROTECTION to enable PAUTH.
 ENABLE_PAUTH			:= 0
 
+# By default BL31 encryption disabled
+ENCRYPT_BL31			:= 0
+
+# By default BL32 encryption disabled
+ENCRYPT_BL32			:= 0
+
+# Default dummy firmware encryption key
+ENC_KEY	:= 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
+
+# Default dummy nonce for firmware encryption
+ENC_NONCE			:= 1234567890abcdef12345678
+
 # Build flag to treat usage of deprecated platform and framework APIs as error.
 ERROR_DEPRECATED		:= 0
 
@@ -124,6 +136,9 @@
 # Default FWU_FIP file name
 FWU_FIP_NAME			:= fwu_fip.bin
 
+# By default firmware encryption with SSK
+FW_ENC_STATUS			:= 0
+
 # For Chain of Trust
 GENERATE_COT			:= 0