aboutsummaryrefslogtreecommitdiff
path: root/lib/aes
diff options
context:
space:
mode:
Diffstat (limited to 'lib/aes')
-rw-r--r--lib/aes/Makefile5
-rw-r--r--lib/aes/aes-decrypt.c40
-rw-r--r--lib/aes/aes-encrypt.c153
3 files changed, 198 insertions, 0 deletions
diff --git a/lib/aes/Makefile b/lib/aes/Makefile
new file mode 100644
index 00000000000..daed52a713b
--- /dev/null
+++ b/lib/aes/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2019, Softathome
+
+obj-$(CONFIG_$(SPL_)FIT_CIPHER) += aes-decrypt.o
diff --git a/lib/aes/aes-decrypt.c b/lib/aes/aes-decrypt.c
new file mode 100644
index 00000000000..741102a4723
--- /dev/null
+++ b/lib/aes/aes-decrypt.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019, softathome
+ */
+
+#ifndef USE_HOSTCC
+#include <malloc.h>
+#endif
+#include <image.h>
+#include <uboot_aes.h>
+
+int image_aes_decrypt(struct image_cipher_info *info,
+ const void *cipher, size_t cipher_len,
+ void **data, size_t *size)
+{
+#ifndef USE_HOSTCC
+ unsigned char key_exp[AES256_EXPAND_KEY_LENGTH];
+ unsigned int aes_blocks, key_len = info->cipher->key_len;
+
+ *data = malloc(cipher_len);
+ if (!*data) {
+ printf("Can't allocate memory to decrypt\n");
+ return -ENOMEM;
+ }
+ *size = info->size_unciphered;
+
+ memcpy(&key_exp[0], info->key, key_len);
+
+ /* First we expand the key. */
+ aes_expand_key((u8 *)info->key, key_len, key_exp);
+
+ /* Calculate the number of AES blocks to encrypt. */
+ aes_blocks = DIV_ROUND_UP(cipher_len, AES_BLOCK_LENGTH);
+
+ aes_cbc_decrypt_blocks(key_len, key_exp, (u8 *)info->iv,
+ (u8 *)cipher, *data, aes_blocks);
+#endif
+
+ return 0;
+}
diff --git a/lib/aes/aes-encrypt.c b/lib/aes/aes-encrypt.c
new file mode 100644
index 00000000000..e74e35eaa28
--- /dev/null
+++ b/lib/aes/aes-encrypt.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019,Softathome
+ */
+
+#define OPENSSL_API_COMPAT 0x10101000L
+
+#include "mkimage.h"
+#include <stdio.h>
+#include <string.h>
+#include <image.h>
+#include <time.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+#include <uboot_aes.h>
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+#define HAVE_ERR_REMOVE_THREAD_STATE
+#endif
+
+int image_aes_encrypt(struct image_cipher_info *info,
+ unsigned char *data, int size,
+ unsigned char **cipher, int *cipher_len)
+{
+ EVP_CIPHER_CTX *ctx;
+ unsigned char *buf = NULL;
+ int buf_len, len, ret = 0;
+
+ /* create and initialise the context */
+ ctx = EVP_CIPHER_CTX_new();
+ if (!ctx) {
+ printf("Can't create context\n");
+ return -1;
+ }
+
+ /* allocate a buffer for the result */
+ buf = malloc(size + AES_BLOCK_LENGTH);
+ if (!buf) {
+ printf("Can't allocate memory to encrypt\n");
+ ret = -1;
+ goto out;
+ }
+
+ if (EVP_EncryptInit_ex(ctx, info->cipher->calculate_type(),
+ NULL, info->key, info->iv) != 1) {
+ printf("Can't init encryption\n");
+ ret = -1;
+ goto out;
+ }
+
+ if (EVP_EncryptUpdate(ctx, buf, &len, data, size) != 1) {
+ printf("Can't encrypt data\n");
+ ret = -1;
+ goto out;
+ }
+
+ buf_len = len;
+
+ if (EVP_EncryptFinal_ex(ctx, buf + len, &len) != 1) {
+ printf("Can't finalise the encryption\n");
+ ret = -1;
+ goto out;
+ }
+
+ buf_len += len;
+
+ *cipher = buf;
+ *cipher_len = buf_len;
+
+ out:
+ EVP_CIPHER_CTX_free(ctx);
+ return ret;
+}
+
+int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
+ void *fit, int node_noffset)
+{
+ int parent, node;
+ char name[128];
+ int ret = 0;
+
+ /* Either create or overwrite the named cipher node */
+ parent = fdt_subnode_offset(keydest, 0, FIT_CIPHER_NODENAME);
+ if (parent == -FDT_ERR_NOTFOUND) {
+ parent = fdt_add_subnode(keydest, 0, FIT_CIPHER_NODENAME);
+ if (parent < 0) {
+ ret = parent;
+ if (ret != -FDT_ERR_NOSPACE) {
+ fprintf(stderr,
+ "Couldn't create cipher node: %s\n",
+ fdt_strerror(parent));
+ }
+ }
+ }
+ if (ret)
+ goto done;
+
+ /* Either create or overwrite the named key node */
+ if (info->ivname)
+ snprintf(name, sizeof(name), "key-%s-%s-%s",
+ info->name, info->keyname, info->ivname);
+ else
+ snprintf(name, sizeof(name), "key-%s-%s",
+ info->name, info->keyname);
+
+ node = fdt_subnode_offset(keydest, parent, name);
+ if (node == -FDT_ERR_NOTFOUND) {
+ node = fdt_add_subnode(keydest, parent, name);
+ if (node < 0) {
+ ret = node;
+ if (ret != -FDT_ERR_NOSPACE) {
+ fprintf(stderr,
+ "Could not create key subnode: %s\n",
+ fdt_strerror(node));
+ }
+ }
+ } else if (node < 0) {
+ fprintf(stderr, "Cannot select keys parent: %s\n",
+ fdt_strerror(node));
+ ret = node;
+ }
+
+ if (ret)
+ goto done;
+
+ if (info->ivname)
+ /* Store the IV in the u-boot device tree */
+ ret = fdt_setprop(keydest, node, "iv",
+ info->iv, info->cipher->iv_len);
+ else
+ /* Store the IV in the FIT image */
+ ret = fdt_setprop(fit, node_noffset, "iv",
+ info->iv, info->cipher->iv_len);
+
+ if (!ret)
+ ret = fdt_setprop(keydest, node, "key",
+ info->key, info->cipher->key_len);
+
+ if (!ret)
+ ret = fdt_setprop_u32(keydest, node, "key-len",
+ info->cipher->key_len);
+
+done:
+ if (ret)
+ ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
+
+ return ret;
+}