mkimage: fit: add support to encrypt image with aes

This commit add the support of encrypting image with aes
in mkimage. To enable the ciphering, a node cipher with
a reference to a key and IV (Initialization Vector) must
be added to the its file. Then mkimage add the encrypted
image to the FIT and add the key and IV to the u-boot
device tree.

Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
diff --git a/common/Makefile b/common/Makefile
index 029cc0f..5f62b8d 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -113,6 +113,7 @@
 obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
 obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
 obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-sig.o
+obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
 obj-$(CONFIG_IO_TRACE) += iotrace.o
 obj-y += memsize.o
 obj-y += stdio.o
diff --git a/common/image-cipher.c b/common/image-cipher.c
new file mode 100644
index 0000000..ab8b45b
--- /dev/null
+++ b/common/image-cipher.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019, Softathome
+ */
+
+#ifdef USE_HOSTCC
+#include "mkimage.h"
+#include <time.h>
+#else
+#include <common.h>
+#include <malloc.h>
+DECLARE_GLOBAL_DATA_PTR;
+#endif /* !USE_HOSTCC*/
+#include <image.h>
+#include <uboot_aes.h>
+#include <u-boot/aes.h>
+
+struct cipher_algo cipher_algos[] = {
+	{
+		.name = "aes128",
+		.key_len = AES128_KEY_LENGTH,
+		.iv_len  = AES_BLOCK_LENGTH,
+#if IMAGE_ENABLE_ENCRYPT
+		.calculate_type = EVP_aes_128_cbc,
+#endif
+		.encrypt = image_aes_encrypt,
+		.add_cipher_data = image_aes_add_cipher_data
+	},
+	{
+		.name = "aes192",
+		.key_len = AES192_KEY_LENGTH,
+		.iv_len  = AES_BLOCK_LENGTH,
+#if IMAGE_ENABLE_ENCRYPT
+		.calculate_type = EVP_aes_192_cbc,
+#endif
+		.encrypt = image_aes_encrypt,
+		.add_cipher_data = image_aes_add_cipher_data
+	},
+	{
+		.name = "aes256",
+		.key_len = AES256_KEY_LENGTH,
+		.iv_len  = AES_BLOCK_LENGTH,
+#if IMAGE_ENABLE_ENCRYPT
+		.calculate_type = EVP_aes_256_cbc,
+#endif
+		.encrypt = image_aes_encrypt,
+		.add_cipher_data = image_aes_add_cipher_data
+	}
+};
+
+struct cipher_algo *image_get_cipher_algo(const char *full_name)
+{
+	int i;
+	const char *name;
+
+	for (i = 0; i < ARRAY_SIZE(cipher_algos); i++) {
+		name = cipher_algos[i].name;
+		if (!strncmp(name, full_name, strlen(name)))
+			return &cipher_algos[i];
+	}
+
+	return NULL;
+}
diff --git a/common/image-fit.c b/common/image-fit.c
index 231612f..6b50ceb 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1080,6 +1080,33 @@
 	return 0;
 }
 
+/**
+ * fit_image_cipher_get_algo - get cipher algorithm name
+ * @fit: pointer to the FIT format image header
+ * @noffset: cipher node offset
+ * @algo: double pointer to char, will hold pointer to the algorithm name
+ *
+ * fit_image_cipher_get_algo() finds cipher algorithm property in a given
+ * cipher node. If the property is found its data start address is returned
+ * to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
+{
+	int len;
+
+	*algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
+	if (!*algo) {
+		fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
+		return -1;
+	}
+
+	return 0;
+}
+
 ulong fit_get_end(const void *fit)
 {
 	return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));