blob: 90e1407b4f094cd69db33bbd871406af87989df2 [file] [log] [blame]
Philippe Reynes3148e422019-12-18 18:25:41 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2019,Softathome
4 */
Heinrich Schuchardt43ee8012021-12-18 11:25:12 +01005
6#define OPENSSL_API_COMPAT 0x10101000L
7
Philippe Reynes3148e422019-12-18 18:25:41 +01008#include "mkimage.h"
9#include <stdio.h>
10#include <string.h>
11#include <image.h>
12#include <time.h>
13#include <openssl/bn.h>
14#include <openssl/rsa.h>
15#include <openssl/pem.h>
16#include <openssl/err.h>
17#include <openssl/ssl.h>
18#include <openssl/evp.h>
19#include <openssl/engine.h>
20#include <uboot_aes.h>
21
22#if OPENSSL_VERSION_NUMBER >= 0x10000000L
23#define HAVE_ERR_REMOVE_THREAD_STATE
24#endif
25
26int image_aes_encrypt(struct image_cipher_info *info,
27 unsigned char *data, int size,
28 unsigned char **cipher, int *cipher_len)
29{
30 EVP_CIPHER_CTX *ctx;
31 unsigned char *buf = NULL;
32 int buf_len, len, ret = 0;
33
34 /* create and initialise the context */
35 ctx = EVP_CIPHER_CTX_new();
36 if (!ctx) {
37 printf("Can't create context\n");
38 return -1;
39 }
40
41 /* allocate a buffer for the result */
42 buf = malloc(size + AES_BLOCK_LENGTH);
43 if (!buf) {
44 printf("Can't allocate memory to encrypt\n");
45 ret = -1;
46 goto out;
47 }
48
49 if (EVP_EncryptInit_ex(ctx, info->cipher->calculate_type(),
50 NULL, info->key, info->iv) != 1) {
51 printf("Can't init encryption\n");
52 ret = -1;
53 goto out;
54 }
55
56 if (EVP_EncryptUpdate(ctx, buf, &len, data, size) != 1) {
57 printf("Can't encrypt data\n");
58 ret = -1;
59 goto out;
60 }
61
62 buf_len = len;
63
64 if (EVP_EncryptFinal_ex(ctx, buf + len, &len) != 1) {
65 printf("Can't finalise the encryption\n");
66 ret = -1;
67 goto out;
68 }
69
70 buf_len += len;
71
72 *cipher = buf;
73 *cipher_len = buf_len;
74
75 out:
76 EVP_CIPHER_CTX_free(ctx);
77 return ret;
78}
79
Philippe Reynes64d67c42020-09-17 15:01:46 +020080int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
81 void *fit, int node_noffset)
Philippe Reynes3148e422019-12-18 18:25:41 +010082{
83 int parent, node;
84 char name[128];
85 int ret = 0;
86
Paul HENRYS07019912024-11-25 18:47:15 +010087 if (!keydest && !info->ivname) {
88 /* At least, store the IV in the FIT image */
89 ret = fdt_setprop(fit, node_noffset, "iv",
90 info->iv, info->cipher->iv_len);
91 goto done;
92 }
93
Philippe Reynes3148e422019-12-18 18:25:41 +010094 /* Either create or overwrite the named cipher node */
95 parent = fdt_subnode_offset(keydest, 0, FIT_CIPHER_NODENAME);
96 if (parent == -FDT_ERR_NOTFOUND) {
97 parent = fdt_add_subnode(keydest, 0, FIT_CIPHER_NODENAME);
98 if (parent < 0) {
99 ret = parent;
100 if (ret != -FDT_ERR_NOSPACE) {
101 fprintf(stderr,
102 "Couldn't create cipher node: %s\n",
103 fdt_strerror(parent));
104 }
105 }
106 }
107 if (ret)
108 goto done;
109
110 /* Either create or overwrite the named key node */
Philippe Reynes64d67c42020-09-17 15:01:46 +0200111 if (info->ivname)
112 snprintf(name, sizeof(name), "key-%s-%s-%s",
113 info->name, info->keyname, info->ivname);
114 else
115 snprintf(name, sizeof(name), "key-%s-%s",
116 info->name, info->keyname);
117
Philippe Reynes3148e422019-12-18 18:25:41 +0100118 node = fdt_subnode_offset(keydest, parent, name);
119 if (node == -FDT_ERR_NOTFOUND) {
120 node = fdt_add_subnode(keydest, parent, name);
121 if (node < 0) {
122 ret = node;
123 if (ret != -FDT_ERR_NOSPACE) {
124 fprintf(stderr,
125 "Could not create key subnode: %s\n",
126 fdt_strerror(node));
127 }
128 }
129 } else if (node < 0) {
130 fprintf(stderr, "Cannot select keys parent: %s\n",
131 fdt_strerror(node));
132 ret = node;
133 }
134
Philippe Reynes64d67c42020-09-17 15:01:46 +0200135 if (ret)
136 goto done;
137
138 if (info->ivname)
139 /* Store the IV in the u-boot device tree */
Philippe Reynes3148e422019-12-18 18:25:41 +0100140 ret = fdt_setprop(keydest, node, "iv",
141 info->iv, info->cipher->iv_len);
Philippe Reynes64d67c42020-09-17 15:01:46 +0200142 else
143 /* Store the IV in the FIT image */
144 ret = fdt_setprop(fit, node_noffset, "iv",
145 info->iv, info->cipher->iv_len);
Philippe Reynes3148e422019-12-18 18:25:41 +0100146
147 if (!ret)
148 ret = fdt_setprop(keydest, node, "key",
149 info->key, info->cipher->key_len);
150
151 if (!ret)
152 ret = fdt_setprop_u32(keydest, node, "key-len",
153 info->cipher->key_len);
154
155done:
156 if (ret)
157 ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
158
159 return ret;
160}