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