• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
image_aes_encrypt(struct image_cipher_info * info,unsigned char * data,int size,unsigned char ** cipher,int * cipher_len)23 int 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 
image_aes_add_cipher_data(struct image_cipher_info * info,void * keydest)77 int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest)
78 {
79 	int parent, node;
80 	char name[128];
81 	int ret = 0;
82 
83 	/* Either create or overwrite the named cipher node */
84 	parent = fdt_subnode_offset(keydest, 0, FIT_CIPHER_NODENAME);
85 	if (parent == -FDT_ERR_NOTFOUND) {
86 		parent = fdt_add_subnode(keydest, 0, FIT_CIPHER_NODENAME);
87 		if (parent < 0) {
88 			ret = parent;
89 			if (ret != -FDT_ERR_NOSPACE) {
90 				fprintf(stderr,
91 					"Couldn't create cipher node: %s\n",
92 					fdt_strerror(parent));
93 			}
94 		}
95 	}
96 	if (ret)
97 		goto done;
98 
99 	/* Either create or overwrite the named key node */
100 	snprintf(name, sizeof(name), "key-%s-%s-%s",
101 		 info->name, info->keyname, info->ivname);
102 	node = fdt_subnode_offset(keydest, parent, name);
103 	if (node == -FDT_ERR_NOTFOUND) {
104 		node = fdt_add_subnode(keydest, parent, name);
105 		if (node < 0) {
106 			ret = node;
107 			if (ret != -FDT_ERR_NOSPACE) {
108 				fprintf(stderr,
109 					"Could not create key subnode: %s\n",
110 					fdt_strerror(node));
111 			}
112 		}
113 	} else if (node < 0) {
114 		fprintf(stderr, "Cannot select keys parent: %s\n",
115 			fdt_strerror(node));
116 		ret = node;
117 	}
118 
119 	if (!ret)
120 		ret = fdt_setprop(keydest, node, "iv",
121 				  info->iv, info->cipher->iv_len);
122 
123 	if (!ret)
124 		ret = fdt_setprop(keydest, node, "key",
125 				  info->key, info->cipher->key_len);
126 
127 	if (!ret)
128 		ret = fdt_setprop_u32(keydest, node, "key-len",
129 				      info->cipher->key_len);
130 
131 done:
132 	if (ret)
133 		ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
134 
135 	return ret;
136 }
137