// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2019,Softathome */ #define OPENSSL_API_COMPAT 0x10101000L #include "mkimage.h" #include #include #include #include #include #include #include #include #include #include #include #include #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; }