// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2019,Softathome
 */
#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)
{
	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 */
	snprintf(name, sizeof(name), "key-%s-%s-%s",
		 info->name, info->keyname, info->ivname);
	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)
		ret = fdt_setprop(keydest, node, "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;
}
