summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-01-01 20:48:05 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-01-16 19:58:24 +0100
commit2b20026dd755706934f8f8e1a192bffdfc3d717c (patch)
tree3c8bb119ab5e9d3f62093563e99609c7dc2a8f2f
parentcb8a98e365c0b69e068dc077eb5d68dd4a29a1ad (diff)
downloadrockbox-2b20026dd755706934f8f8e1a192bffdfc3d717c.tar.gz
rockbox-2b20026dd755706934f8f8e1a192bffdfc3d717c.zip
imxtools/sbtools: rework cryptography
It was a mess, a mix of crypto_* and cbc_mac calls. I made everything call crypto functions, and also separate key setup from cryptographic operations, this will be useful to speed up the code in the upcoming commits. Drop support for "usbotp" key, since the crypto code for that was never mainlined and we can always get the keys from a device as long as we have code execution (using the DCP debug registers). Change-Id: I7aa24d12207ffb744225d1b9cc7cb1dc7281dd22
-rw-r--r--rbutil/mkimxboot/Makefile2
-rw-r--r--utils/imxtools/sbtools/Makefile11
-rw-r--r--utils/imxtools/sbtools/crypto.c188
-rw-r--r--utils/imxtools/sbtools/crypto.cpp55
-rw-r--r--utils/imxtools/sbtools/crypto.h49
-rw-r--r--utils/imxtools/sbtools/misc.c29
-rw-r--r--utils/imxtools/sbtools/rsrc.h3
-rw-r--r--utils/imxtools/sbtools/sb.c148
-rw-r--r--utils/imxtools/sbtools/sb.h3
-rw-r--r--utils/imxtools/sbtools/sb1.h3
10 files changed, 172 insertions, 319 deletions
diff --git a/rbutil/mkimxboot/Makefile b/rbutil/mkimxboot/Makefile
index 3aa8438256..7441e162c2 100644
--- a/rbutil/mkimxboot/Makefile
+++ b/rbutil/mkimxboot/Makefile
@@ -14,7 +14,7 @@ CFLAGS += -std=gnu99 -g -O3
14OUTPUT = mkimxboot 14OUTPUT = mkimxboot
15 15
16# inputs for lib 16# inputs for lib
17IMXTOOLS_SOURCES = misc.c sb.c crypto.c crc.c aes128.c sha1.c elf.c 17IMXTOOLS_SOURCES = misc.c sb.c crypto.cpp crc.c aes128.c sha1.c elf.c
18LIBSOURCES := dualboot.c mkimxboot.c md5.c \ 18LIBSOURCES := dualboot.c mkimxboot.c md5.c \
19 $(addprefix $(IMXTOOLS_DIR),$(IMXTOOLS_SOURCES)) 19 $(addprefix $(IMXTOOLS_DIR),$(IMXTOOLS_SOURCES))
20# inputs for binary only 20# inputs for binary only
diff --git a/utils/imxtools/sbtools/Makefile b/utils/imxtools/sbtools/Makefile
index 13b0a1280f..2dad20fe0c 100644
--- a/utils/imxtools/sbtools/Makefile
+++ b/utils/imxtools/sbtools/Makefile
@@ -1,7 +1,9 @@
1DEFINES=-DCRYPTO_LIBUSB 1DEFINES=
2CC=gcc 2CC=gcc
3LD=gcc 3CXX=g++
4CFLAGS=-O3 -g -std=c99 -W -Wall `pkg-config --cflags libusb-1.0` $(DEFINES) 4LD=g++
5CFLAGS=-O3 -g -std=c99 -Wall `pkg-config --cflags libusb-1.0` $(DEFINES)
6CXXFLAGS=-O3 -g -Wall $(DEFINES)
5LDFLAGS=`pkg-config --libs libusb-1.0` 7LDFLAGS=`pkg-config --libs libusb-1.0`
6BINS=elftosb sbtoelf sbloader rsrctool elftosb1 8BINS=elftosb sbtoelf sbloader rsrctool elftosb1
7 9
@@ -10,6 +12,9 @@ all: $(BINS)
10%.o: %.c 12%.o: %.c
11 $(CC) $(CFLAGS) -c -o $@ $< 13 $(CC) $(CFLAGS) -c -o $@ $<
12 14
15%.o: %.cpp
16 $(CXX) $(CXXFLAGS) -c -o $@ $<
17
13sbtoelf: sbtoelf.o crc.o crypto.o aes128.o sha1.o xorcrypt.o dbparser.o elf.o misc.o sb.o sb1.o 18sbtoelf: sbtoelf.o crc.o crypto.o aes128.o sha1.o xorcrypt.o dbparser.o elf.o misc.o sb.o sb1.o
14 $(LD) -o $@ $^ $(LDFLAGS) 19 $(LD) -o $@ $^ $(LDFLAGS)
15 20
diff --git a/utils/imxtools/sbtools/crypto.c b/utils/imxtools/sbtools/crypto.c
deleted file mode 100644
index 4f7b799dd9..0000000000
--- a/utils/imxtools/sbtools/crypto.c
+++ /dev/null
@@ -1,188 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "crypto.h"
22#include <stdio.h>
23#include <stdbool.h>
24#ifdef CRYPTO_LIBUSB
25#include "libusb.h"
26#endif
27#include "misc.h"
28
29static enum crypto_method_t cur_method = CRYPTO_NONE;
30static byte key[16];
31static uint16_t usb_vid, usb_pid;
32
33void crypto_setup(enum crypto_method_t method, void *param)
34{
35 cur_method = method;
36 switch(method)
37 {
38 case CRYPTO_KEY:
39 memcpy(key, param, sizeof(key));
40 break;
41 case CRYPTO_USBOTP:
42 {
43 uint32_t value = *(uint32_t *)param;
44 usb_vid = value >> 16;
45 usb_pid = value & 0xffff;
46 break;
47 }
48 default:
49 break;
50 }
51}
52
53int crypto_apply(
54 byte *in_data, /* Input data */
55 byte *out_data, /* Output data (or NULL) */
56 int nr_blocks, /* Number of blocks (one block=16 bytes) */
57 byte iv[16], /* Key */
58 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */
59 int encrypt)
60{
61 if(cur_method == CRYPTO_KEY)
62 {
63 cbc_mac(in_data, out_data, nr_blocks, key, iv, out_cbc_mac, encrypt);
64 return CRYPTO_ERROR_SUCCESS;
65 }
66 #ifdef CRYPTO_LIBUSB
67 else if(cur_method == CRYPTO_USBOTP)
68 {
69 if(out_cbc_mac && !encrypt)
70 memcpy(*out_cbc_mac, in_data + 16 * (nr_blocks - 1), 16);
71
72 libusb_device_handle *handle = NULL;
73 libusb_context *ctx;
74 /* init library */
75 libusb_init(&ctx);
76 libusb_set_debug(NULL,3);
77 /* open device */
78 handle = libusb_open_device_with_vid_pid(ctx, usb_vid, usb_pid);
79 if(handle == NULL)
80 {
81 printf("usbotp: cannot open device %04x:%04x\n", usb_vid, usb_pid);
82 return CRYPTO_ERROR_NODEVICE;
83 }
84 /* get device pointer */
85 libusb_device *mydev = libusb_get_device(handle);
86 if(g_debug)
87 printf("usbotp: device found at %d:%d\n", libusb_get_bus_number(mydev),
88 libusb_get_device_address(mydev));
89 int config_id;
90 /* explore configuration */
91 libusb_get_configuration(handle, &config_id);
92 struct libusb_config_descriptor *config;
93 libusb_get_active_config_descriptor(mydev, &config);
94
95 if(g_debug)
96 {
97 printf("usbotp: configuration: %d\n", config_id);
98 printf("usbotp: interfaces: %d\n", config->bNumInterfaces);
99 }
100
101 const struct libusb_endpoint_descriptor *endp = NULL;
102 int intf, intf_alt;
103 for(intf = 0; intf < config->bNumInterfaces; intf++)
104 for(intf_alt = 0; intf_alt < config->interface[intf].num_altsetting; intf_alt++)
105 for(int ep = 0; ep < config->interface[intf].altsetting[intf_alt].bNumEndpoints; ep++)
106 {
107 endp = &config->interface[intf].altsetting[intf_alt].endpoint[ep];
108 if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_INTERRUPT &&
109 (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
110 goto Lfound;
111 }
112 libusb_close(handle);
113 printf("usbotp: No suitable endpoint found\n");
114 return CRYPTO_ERROR_BADENDP;
115
116 if(g_debug)
117 {
118 printf("usbotp: use interface %d, alt %d\n", intf, intf_alt);
119 printf("usbotp: use endpoint %d\n", endp->bEndpointAddress);
120 }
121 Lfound:
122 if(libusb_claim_interface(handle, intf) != 0)
123 {
124 if(g_debug)
125 printf("usbotp: claim error\n");
126 return CRYPTO_ERROR_CLAIMFAIL;
127 }
128
129 int buffer_size = 16 + 16 * nr_blocks;
130 unsigned char *buffer = xmalloc(buffer_size);
131 memcpy(buffer, iv, 16);
132 memcpy(buffer + 16, in_data, 16 * nr_blocks);
133 int ret = libusb_control_transfer(handle,
134 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE,
135 0xaa, encrypt ? 0xeeee : 0xdddd, 0, buffer, buffer_size, 1000);
136 if(ret < 0)
137 {
138 if(g_debug)
139 printf("usbotp: control transfer failed: %d\n", ret);
140 libusb_release_interface(handle, intf);
141 libusb_close(handle);
142 return CRYPTO_ERROR_DEVREJECT;
143 }
144
145 int recv_size;
146 ret = libusb_interrupt_transfer(handle, endp->bEndpointAddress, buffer,
147 buffer_size, &recv_size, 1000);
148 libusb_release_interface(handle, intf);
149 libusb_close(handle);
150
151 if(ret < 0)
152 {
153 if(g_debug)
154 printf("usbotp: interrupt transfer failed: %d\n", ret);
155 return CRYPTO_ERROR_DEVSILENT;
156 }
157 if(recv_size != buffer_size)
158 {
159 if(g_debug)
160 printf("usbotp: device returned %d bytes, expected %d\n", recv_size,
161 buffer_size);
162 return CRYPTO_ERROR_DEVERR;
163 }
164
165 if(out_data)
166 memcpy(out_data, buffer + 16, 16 * nr_blocks);
167 if(out_cbc_mac && encrypt)
168 memcpy(*out_cbc_mac, buffer + buffer_size - 16, 16);
169
170 return CRYPTO_ERROR_SUCCESS;
171 }
172 #endif
173 else
174 return CRYPTO_ERROR_BADSETUP;
175}
176
177int crypto_cbc(
178 byte *in_data, /* Input data */
179 byte *out_data, /* Output data (or NULL) */
180 int nr_blocks, /* Number of blocks (one block=16 bytes) */
181 struct crypto_key_t *key, /* Key */
182 byte iv[16], /* IV */
183 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */
184 int encrypt)
185{
186 crypto_setup(key->method, (void *)key->u.param);
187 return crypto_apply(in_data, out_data, nr_blocks, iv, out_cbc_mac, encrypt);
188}
diff --git a/utils/imxtools/sbtools/crypto.cpp b/utils/imxtools/sbtools/crypto.cpp
new file mode 100644
index 0000000000..35068c3e7d
--- /dev/null
+++ b/utils/imxtools/sbtools/crypto.cpp
@@ -0,0 +1,55 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "crypto.h"
22#include "misc.h"
23
24static enum crypto_method_t g_cur_method = CRYPTO_NONE;
25static byte g_key[16];
26
27int crypto_setup(struct crypto_key_t *key)
28{
29 g_cur_method = key->method;
30 switch(g_cur_method)
31 {
32 case CRYPTO_KEY:
33 memcpy(g_key, key->u.key, 16);
34 return CRYPTO_ERROR_SUCCESS;
35 default:
36 return CRYPTO_ERROR_BADSETUP;
37 }
38}
39
40int crypto_apply(
41 byte *in_data, /* Input data */
42 byte *out_data, /* Output data (or NULL) */
43 int nr_blocks, /* Number of blocks (one block=16 bytes) */
44 byte iv[16], /* Key */
45 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */
46 bool encrypt)
47{
48 if(g_cur_method == CRYPTO_KEY)
49 {
50 cbc_mac(in_data, out_data, nr_blocks, g_key, iv, out_cbc_mac, encrypt);
51 return CRYPTO_ERROR_SUCCESS;
52 }
53 else
54 return CRYPTO_ERROR_BADSETUP;
55}
diff --git a/utils/imxtools/sbtools/crypto.h b/utils/imxtools/sbtools/crypto.h
index 6751c2e861..9944289a4f 100644
--- a/utils/imxtools/sbtools/crypto.h
+++ b/utils/imxtools/sbtools/crypto.h
@@ -24,6 +24,11 @@
24#include <stdio.h> 24#include <stdio.h>
25#include <stdint.h> 25#include <stdint.h>
26#include <string.h> 26#include <string.h>
27#include <stdbool.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
27 32
28typedef uint8_t byte; 33typedef uint8_t byte;
29 34
@@ -48,32 +53,8 @@ enum crypto_method_t
48 CRYPTO_NONE, /* disable */ 53 CRYPTO_NONE, /* disable */
49 CRYPTO_KEY, /* key */ 54 CRYPTO_KEY, /* key */
50 CRYPTO_XOR_KEY, /* XOR key */ 55 CRYPTO_XOR_KEY, /* XOR key */
51 CRYPTO_USBOTP, /* use usbotp device */
52}; 56};
53 57
54/* parameter can be:
55 * - CRYPTO_KEY: array of 16-bytes (the key)
56 * - CRYPTO_USBOTP: 32-bit integer: vid << 16 | pid */
57void crypto_setup(enum crypto_method_t method, void *param);
58
59#define CRYPTO_ERROR_SUCCESS 0
60#define CRYPTO_ERROR_BADSETUP -1 /* bad crypto setup */
61#define CRYPTO_ERROR_NODEVICE -2 /* no device with vid:pid */
62#define CRYPTO_ERROR_BADENDP -3 /* device doesn't have the required endpoints */
63#define CRYPTO_ERROR_CLAIMFAIL -4 /* device interface claim error */
64#define CRYPTO_ERROR_DEVREJECT -5 /* device rejected cypto operation */
65#define CRYPTO_ERROR_DEVSILENT -6 /* device did not notify completion */
66#define CRYPTO_ERROR_DEVERR -7 /* device did something wrong (like return too small buffer) */
67#define CRYPTO_NUM_ERRORS 8
68/* return 0 on success, <0 on error */
69int crypto_apply(
70 byte *in_data, /* Input data */
71 byte *out_data, /* Output data (or NULL) */
72 int nr_blocks, /* Number of blocks (one block=16 bytes) */
73 byte iv[16], /* IV */
74 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */
75 int encrypt);
76
77union xorcrypt_key_t 58union xorcrypt_key_t
78{ 59{
79 uint8_t key[64]; 60 uint8_t key[64];
@@ -88,19 +69,25 @@ struct crypto_key_t
88 { 69 {
89 byte key[16]; 70 byte key[16];
90 union xorcrypt_key_t xor_key[2]; 71 union xorcrypt_key_t xor_key[2];
91 uint32_t vid_pid;
92 byte param[0];
93 }u; 72 }u;
94}; 73};
95 74
96int crypto_cbc( 75#define CRYPTO_ERROR_SUCCESS 0
76#define CRYPTO_ERROR_BADSETUP -1
77
78/* parameter can be:
79 * - CRYPTO_KEY: array of 16-bytes (the key)
80 * return 0 on success, <0 on error */
81int crypto_setup(struct crypto_key_t *key);
82
83/* return 0 on success, <0 on error */
84int crypto_apply(
97 byte *in_data, /* Input data */ 85 byte *in_data, /* Input data */
98 byte *out_data, /* Output data (or NULL) */ 86 byte *out_data, /* Output data (or NULL) */
99 int nr_blocks, /* Number of blocks (one block=16 bytes) */ 87 int nr_blocks, /* Number of blocks (one block=16 bytes) */
100 struct crypto_key_t *key, /* Key */
101 byte iv[16], /* IV */ 88 byte iv[16], /* IV */
102 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */ 89 byte (*out_cbc_mac)[16], /* CBC-MAC of the result (or NULL) */
103 int encrypt); 90 bool encrypt);
104 91
105/* crc.c */ 92/* crc.c */
106uint32_t crc(byte *data, int size); 93uint32_t crc(byte *data, int size);
@@ -127,4 +114,8 @@ uint32_t xor_encrypt(union xorcrypt_key_t keys[2], void *data, int size);
127uint32_t xor_decrypt(union xorcrypt_key_t keys[2], void *data, int size); 114uint32_t xor_decrypt(union xorcrypt_key_t keys[2], void *data, int size);
128void xor_generate_key(uint32_t laserfuse[3], union xorcrypt_key_t key[2]); 115void xor_generate_key(uint32_t laserfuse[3], union xorcrypt_key_t key[2]);
129 116
117#ifdef __cplusplus
118}
119#endif
120
130#endif /* __CRYPTO_H__ */ 121#endif /* __CRYPTO_H__ */
diff --git a/utils/imxtools/sbtools/misc.c b/utils/imxtools/sbtools/misc.c
index b36ab7902f..b3ca23cf77 100644
--- a/utils/imxtools/sbtools/misc.c
+++ b/utils/imxtools/sbtools/misc.c
@@ -118,7 +118,6 @@ bool parse_key(char **pstr, struct crypto_key_t *key)
118 while(isspace(*str)) 118 while(isspace(*str))
119 str++; 119 str++;
120 /* CRYPTO_KEY: 32 hex characters 120 /* CRYPTO_KEY: 32 hex characters
121 * CRYPTO_USBOTP: usbotp(vid:pid) where vid and pid are hex numbers
122 * CRYPTO_XOR_KEY: 256 hex characters */ 121 * CRYPTO_XOR_KEY: 256 hex characters */
123 if(isxdigit(str[0]) && strlen(str) >= 256 && isxdigit(str[32])) 122 if(isxdigit(str[0]) && strlen(str) >= 256 && isxdigit(str[32]))
124 { 123 {
@@ -151,30 +150,7 @@ bool parse_key(char **pstr, struct crypto_key_t *key)
151 return true; 150 return true;
152 } 151 }
153 else 152 else
154 { 153 return false;
155 const char *prefix = "usbotp(";
156 if(strlen(str) < strlen(prefix))
157 return false;
158 if(strncmp(str, prefix, strlen(prefix)) != 0)
159 return false;
160 str += strlen(prefix);
161 /* vid */
162 long vid = strtol(str, &str, 16);
163 if(vid < 0 || vid > 0xffff)
164 return false;
165 if(*str++ != ':')
166 return false;
167 /* pid */
168 long pid = strtol(str, &str, 16);
169 if(pid < 0 || pid > 0xffff)
170 return false;
171 if(*str++ != ')')
172 return false;
173 *pstr = str;
174 key->method = CRYPTO_USBOTP;
175 key->u.vid_pid = vid << 16 | pid;
176 return true;
177 }
178} 154}
179 155
180void add_keys(key_array_t ka, int kac) 156void add_keys(key_array_t ka, int kac)
@@ -278,9 +254,6 @@ void print_key(void *user, misc_printf_t printf, struct crypto_key_t *key, bool
278 case CRYPTO_KEY: 254 case CRYPTO_KEY:
279 print_hex(user, printf, key->u.key, 16, false); 255 print_hex(user, printf, key->u.key, 16, false);
280 break; 256 break;
281 case CRYPTO_USBOTP:
282 printf(user, "USB-OTP(%04x:%04x)", key->u.vid_pid >> 16, key->u.vid_pid & 0xffff);
283 break;
284 case CRYPTO_NONE: 257 case CRYPTO_NONE:
285 printf(user, "none"); 258 printf(user, "none");
286 break; 259 break;
diff --git a/utils/imxtools/sbtools/rsrc.h b/utils/imxtools/sbtools/rsrc.h
index c3e0bdfb37..9dfd27b465 100644
--- a/utils/imxtools/sbtools/rsrc.h
+++ b/utils/imxtools/sbtools/rsrc.h
@@ -73,8 +73,7 @@ enum rsrc_error_t
73 RSRC_FORMAT_ERROR = -5, 73 RSRC_FORMAT_ERROR = -5,
74 RSRC_CHECKSUM_ERROR = -6, 74 RSRC_CHECKSUM_ERROR = -6,
75 RSRC_NO_VALID_KEY = -7, 75 RSRC_NO_VALID_KEY = -7,
76 RSRC_FIRST_CRYPTO_ERROR = -8, 76 RSRC_CRYPTO_ERROR = -8,
77 RSRC_LAST_CRYPTO_ERROR = RSRC_FIRST_CRYPTO_ERROR - CRYPTO_NUM_ERRORS,
78}; 77};
79 78
80enum rsrc_error_t rsrc_write_file(struct rsrc_file_t *rsrc, const char *filename); 79enum rsrc_error_t rsrc_write_file(struct rsrc_file_t *rsrc, const char *filename);
diff --git a/utils/imxtools/sbtools/sb.c b/utils/imxtools/sbtools/sb.c
index 145df39762..ff8e0da3ee 100644
--- a/utils/imxtools/sbtools/sb.c
+++ b/utils/imxtools/sbtools/sb.c
@@ -322,6 +322,12 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
322 byte *buf = xmalloc(sb_hdr.image_size * BLOCK_SIZE); 322 byte *buf = xmalloc(sb_hdr.image_size * BLOCK_SIZE);
323 byte *buf_p = buf; 323 byte *buf_p = buf;
324 #define write(p, sz) do { memcpy(buf_p, p, sz); buf_p += sz; } while(0) 324 #define write(p, sz) do { memcpy(buf_p, p, sz); buf_p += sz; } while(0)
325 #define check_crypto(expr) \
326 do { int err = expr; \
327 if(err != CRYPTO_ERROR_SUCCESS) { \
328 free(cbc_macs); \
329 cprintf(u, true, GREY, "Crypto error: %d\n", err); \
330 return SB_CRYPTO_ERROR; } } while(0)
325 331
326 sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); 332 sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr));
327 write(&sb_hdr, sizeof(sb_hdr)); 333 write(&sb_hdr, sizeof(sb_hdr));
@@ -330,8 +336,11 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
330 336
331 /* update CBC-MACs */ 337 /* update CBC-MACs */
332 for(int i = 0; i < g_nr_keys; i++) 338 for(int i = 0; i < g_nr_keys; i++)
333 crypto_cbc((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, &g_key_array[i], 339 {
334 cbc_macs[i], &cbc_macs[i], 1); 340 check_crypto(crypto_setup(&g_key_array[i]));
341 check_crypto(crypto_apply((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE,
342 cbc_macs[i], &cbc_macs[i], true));
343 }
335 344
336 /* produce and write section headers */ 345 /* produce and write section headers */
337 for(int i = 0; i < sb_hdr.nr_sections; i++) 346 for(int i = 0; i < sb_hdr.nr_sections; i++)
@@ -342,23 +351,23 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
342 write(&sb_sec_hdr, sizeof(sb_sec_hdr)); 351 write(&sb_sec_hdr, sizeof(sb_sec_hdr));
343 /* update CBC-MACs */ 352 /* update CBC-MACs */
344 for(int j = 0; j < g_nr_keys; j++) 353 for(int j = 0; j < g_nr_keys; j++)
345 crypto_cbc((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE, 354 {
346 &g_key_array[j], cbc_macs[j], &cbc_macs[j], 1); 355 check_crypto(crypto_setup(&g_key_array[j]));
356 check_crypto(crypto_apply((byte *)&sb_sec_hdr, NULL,
357 sizeof(sb_sec_hdr) / BLOCK_SIZE, cbc_macs[j], &cbc_macs[j], true));
358 }
347 } 359 }
348 /* produce key dictionary */ 360 /* produce key dictionary */
349 for(int i = 0; i < g_nr_keys; i++) 361 for(int i = 0; i < g_nr_keys; i++)
350 { 362 {
351 struct sb_key_dictionary_entry_t entry; 363 struct sb_key_dictionary_entry_t entry;
352 memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); 364 memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16);
353 crypto_cbc(real_key.u.key, entry.key, 1, &g_key_array[i], 365 check_crypto(crypto_setup(&g_key_array[i]));
354 crypto_iv, NULL, 1); 366 check_crypto(crypto_apply(real_key.u.key, entry.key, 1, crypto_iv, NULL, true));
355
356 write(&entry, sizeof(entry)); 367 write(&entry, sizeof(entry));
357 sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); 368 sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry));
358 } 369 }
359 370
360 free(cbc_macs);
361
362 /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */ 371 /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */
363 /* Image crafting, don't use it unless you understand what you do */ 372 /* Image crafting, don't use it unless you understand what you do */
364 if(sb->override_real_key) 373 if(sb->override_real_key)
@@ -388,6 +397,8 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
388 write(data, init_gap); 397 write(data, init_gap);
389 free(data); 398 free(data);
390 } 399 }
400 /* setup real key */
401 check_crypto(crypto_setup(&real_key));
391 /* produce sections data */ 402 /* produce sections data */
392 for(int i = 0; i< sb_hdr.nr_sections; i++) 403 for(int i = 0; i< sb_hdr.nr_sections; i++)
393 { 404 {
@@ -395,8 +406,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
395 struct sb_instruction_tag_t tag_cmd; 406 struct sb_instruction_tag_t tag_cmd;
396 produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); 407 produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections);
397 if(g_nr_keys > 0) 408 if(g_nr_keys > 0)
398 crypto_cbc((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, 409 {
399 &real_key, crypto_iv, NULL, 1); 410 check_crypto(crypto_apply((byte *)&tag_cmd, (byte *)&tag_cmd,
411 sizeof(tag_cmd) / BLOCK_SIZE, crypto_iv, NULL, true));
412 }
400 sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); 413 sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd));
401 write(&tag_cmd, sizeof(tag_cmd)); 414 write(&tag_cmd, sizeof(tag_cmd));
402 /* produce other commands */ 415 /* produce other commands */
@@ -411,8 +424,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
411 struct sb_instruction_common_t cmd; 424 struct sb_instruction_common_t cmd;
412 produce_sb_instruction(inst, &cmd, u, cprintf); 425 produce_sb_instruction(inst, &cmd, u, cprintf);
413 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) 426 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext)
414 crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, 427 {
415 &real_key, cur_cbc_mac, &cur_cbc_mac, 1); 428 check_crypto(crypto_apply((byte *)&cmd, (byte *)&cmd,
429 sizeof(cmd) / BLOCK_SIZE, cur_cbc_mac, &cur_cbc_mac, true));
430 }
416 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); 431 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd));
417 write(&cmd, sizeof(cmd)); 432 write(&cmd, sizeof(cmd));
418 } 433 }
@@ -424,8 +439,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
424 memcpy(data, inst->data, inst->size); 439 memcpy(data, inst->data, inst->size);
425 memcpy(data + inst->size, inst->padding, inst->padding_size); 440 memcpy(data + inst->size, inst->padding, inst->padding_size);
426 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) 441 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext)
427 crypto_cbc(data, data, sz / BLOCK_SIZE, 442 {
428 &real_key, cur_cbc_mac, &cur_cbc_mac, 1); 443 check_crypto(crypto_apply(data, data, sz / BLOCK_SIZE,
444 cur_cbc_mac, &cur_cbc_mac, true));
445 }
429 sha_1_update(&file_sha1, data, sz); 446 sha_1_update(&file_sha1, data, sz);
430 write(data, sz); 447 write(data, sz);
431 free(data); 448 free(data);
@@ -450,8 +467,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
450 cmd.hdr.opcode = SB_INST_NOP; 467 cmd.hdr.opcode = SB_INST_NOP;
451 cmd.hdr.checksum = instruction_checksum(&cmd.hdr); 468 cmd.hdr.checksum = instruction_checksum(&cmd.hdr);
452 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) 469 if(g_nr_keys > 0 && !sb->sections[i].is_cleartext)
453 crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, 470 {
454 &real_key, cur_cbc_mac, &cur_cbc_mac, 1); 471 check_crypto(crypto_apply((byte *)&cmd, (byte *)&cmd,
472 sizeof(cmd) / BLOCK_SIZE, cur_cbc_mac, &cur_cbc_mac, true));
473 }
455 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); 474 sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd));
456 write(&cmd, sizeof(cmd)); 475 write(&cmd, sizeof(cmd));
457 } 476 }
@@ -463,28 +482,34 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void *
463 sha_1_output(&file_sha1, final_sig); 482 sha_1_output(&file_sha1, final_sig);
464 generate_random_data(final_sig + 20, 12); 483 generate_random_data(final_sig + 20, 12);
465 if(g_nr_keys > 0) 484 if(g_nr_keys > 0)
466 crypto_cbc(final_sig, final_sig, 2, &real_key, crypto_iv, NULL, 1); 485 check_crypto(crypto_apply(final_sig, final_sig, 2, crypto_iv, NULL, true));
467 write(final_sig, 32); 486 write(final_sig, 32);
487
488 free(cbc_macs);
489
468 if(buf_p - buf != sb_hdr.image_size * BLOCK_SIZE) 490 if(buf_p - buf != sb_hdr.image_size * BLOCK_SIZE)
469 { 491 {
470 printf(GREY, "[ERROR][INTERNAL] SB image buffer was not entirely filled !\n"); 492 free(buf);
471 printf(GREY, "[ERROR][INTERNAL] expected %u blocks, got %u\n", 493 printf(GREY, "Internal error: SB image buffer was not entirely filled !\n");
494 printf(GREY, "Internal error: expected %u blocks, got %u\n",
472 (buf_p - buf) / BLOCK_SIZE, sb_hdr.image_size); 495 (buf_p - buf) / BLOCK_SIZE, sb_hdr.image_size);
496 cprintf(u, true, GREY, "Internal error\n");
473 return SB_ERROR; 497 return SB_ERROR;
474 } 498 }
475 499
476 FILE *fd = fopen(filename, "wb"); 500 FILE *fd = fopen(filename, "wb");
477 if(fd == NULL) 501 if(fd == NULL)
478 return SB_OPEN_ERROR; 502 return SB_OPEN_ERROR;
479 if(fwrite(buf, sb_hdr.image_size * BLOCK_SIZE, 1, fd) != 1) 503 int cnt = fwrite(buf, sb_hdr.image_size * BLOCK_SIZE, 1, fd);
480 { 504 if(cnt != 1)
481 free(buf); 505 printf(GREY, "Write error: %m\n");
482 return SB_WRITE_ERROR;
483 }
484 fclose(fd);
485 free(buf); 506 free(buf);
507 fclose(fd);
508 if(cnt != 1)
509 return SB_WRITE_ERROR;
486 510
487 return SB_SUCCESS; 511 return SB_SUCCESS;
512 #undef check_crypto
488 #undef printf 513 #undef printf
489} 514}
490 515
@@ -712,22 +737,28 @@ static void sb_printer(void *user, const char *fmt, ...)
712} 737}
713 738
714struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, void *u, 739struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, void *u,
715 generic_printf_t cprintf, enum sb_error_t *err) 740 generic_printf_t cprintf, enum sb_error_t *out_err)
716{ 741{
717 struct sb_file_t *sb_file = NULL; 742 struct sb_file_t *sb_file = NULL;
718 uint8_t *buf = _buf; 743 uint8_t *buf = _buf;
719 744
720 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) 745 #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__)
721 #define fatal(e, ...) \ 746 #define fatal(e, ...) \
722 do { if(err) *err = e; \ 747 do { if(out_err) *out_err = e; \
723 cprintf(u, true, GREY, __VA_ARGS__); \ 748 cprintf(u, true, GREY, __VA_ARGS__); \
749 free(cbcmacs); \
724 sb_free(sb_file); \ 750 sb_free(sb_file); \
725 return NULL; } while(0) 751 return NULL; } while(0)
726 struct printer_t printer = {.user = u, .cprintf = cprintf, .color = OFF, .error = false }; 752 struct printer_t printer = {.user = u, .cprintf = cprintf, .color = OFF, .error = false };
727 #define print_hex(c, p, len, nl) \ 753 #define print_hex(c, p, len, nl) \
728 do { printer.color = c; print_hex(&printer, sb_printer, p, len, nl); } while(0) 754 do { printer.color = c; print_hex(&printer, sb_printer, p, len, nl); } while(0)
755 #define check_crypto(expr) \
756 do { int err = expr; \
757 if(err != CRYPTO_ERROR_SUCCESS) \
758 fatal(SB_CRYPTO_ERROR, "Crypto error: %d\n", err); } while(0)
729 759
730 struct sha_1_params_t sha_1_params; 760 struct sha_1_params_t sha_1_params;
761 byte (*cbcmacs)[16] = xmalloc(16 * g_nr_keys);
731 sb_file = xmalloc(sizeof(struct sb_file_t)); 762 sb_file = xmalloc(sizeof(struct sb_file_t));
732 memset(sb_file, 0, sizeof(struct sb_file_t)); 763 memset(sb_file, 0, sizeof(struct sb_file_t));
733 struct sb_header_t *sb_header = (struct sb_header_t *)buf; 764 struct sb_header_t *sb_header = (struct sb_header_t *)buf;
@@ -826,12 +857,12 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
826 printf(YELLOW, "0x%08x\n", sb_header->first_boot_sec_id); 857 printf(YELLOW, "0x%08x\n", sb_header->first_boot_sec_id);
827 858
828 /* encryption cbc-mac */ 859 /* encryption cbc-mac */
829 byte real_key[16]; 860 struct crypto_key_t real_key;
861 real_key.method = CRYPTO_KEY;
830 bool valid_key = false; /* false until a matching key was found */ 862 bool valid_key = false; /* false until a matching key was found */
831 863
832 if(sb_header->nr_keys > 0) 864 if(sb_header->nr_keys > 0)
833 { 865 {
834 byte (*cbcmacs)[16] = xmalloc(16 * g_nr_keys);
835 printf(BLUE, "Encryption keys\n"); 866 printf(BLUE, "Encryption keys\n");
836 for(int i = 0; i < g_nr_keys; i++) 867 for(int i = 0; i < g_nr_keys; i++)
837 { 868 {
@@ -843,13 +874,9 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
843 /* check it */ 874 /* check it */
844 byte zero[16]; 875 byte zero[16];
845 memset(zero, 0, 16); 876 memset(zero, 0, 16);
846 int ret = crypto_cbc(buf, NULL, sb_header->header_size + sb_header->nr_sections, 877 check_crypto(crypto_setup(&g_key_array[i]));
847 &g_key_array[i], zero, &cbcmacs[i], 1); 878 check_crypto(crypto_apply(buf, NULL, sb_header->header_size +
848 if(ret != CRYPTO_ERROR_SUCCESS) 879 sb_header->nr_sections, zero, &cbcmacs[i], true));
849 {
850 free(cbcmacs);
851 fatal(SB_FIRST_CRYPTO_ERROR + ret, "Crypto error: %d", ret);
852 }
853 print_hex(YELLOW, cbcmacs[i], 16, true); 880 print_hex(YELLOW, cbcmacs[i], 16, true);
854 } 881 }
855 882
@@ -878,24 +905,20 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
878 byte decrypted_key[16]; 905 byte decrypted_key[16];
879 byte iv[16]; 906 byte iv[16];
880 memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ 907 memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
881 int ret = crypto_cbc(dict_entry->key, decrypted_key, 1, &g_key_array[idx], iv, NULL, 0); 908 check_crypto(crypto_setup(&g_key_array[idx]));
882 if(ret != CRYPTO_ERROR_SUCCESS) 909 check_crypto(crypto_apply(dict_entry->key, decrypted_key, 1, iv, NULL, false));
883 {
884 free(cbcmacs);
885 fatal(SB_FIRST_CRYPTO_ERROR + ret, "Crypto error: %d\n", ret);
886 }
887 printf(GREEN, " Decrypted key: "); 910 printf(GREEN, " Decrypted key: ");
888 print_hex(YELLOW, decrypted_key, 16, false); 911 print_hex(YELLOW, decrypted_key, 16, false);
889 if(valid_key) 912 if(valid_key)
890 { 913 {
891 if(memcmp(real_key, decrypted_key, 16) == 0) 914 if(memcmp(real_key.u.key, decrypted_key, 16) == 0)
892 printf(RED, " Cross-Check Ok"); 915 printf(RED, " Cross-Check Ok");
893 else 916 else
894 printf(RED, " Cross-Check Failed"); 917 printf(RED, " Cross-Check Failed");
895 } 918 }
896 else 919 else
897 { 920 {
898 memcpy(real_key, decrypted_key, 16); 921 memcpy(real_key.u.key, decrypted_key, 16);
899 valid_key = true; 922 valid_key = true;
900 } 923 }
901 printf(OFF, "\n"); 924 printf(OFF, "\n");
@@ -904,8 +927,6 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
904 printf(RED, " Don't Match\n"); 927 printf(RED, " Don't Match\n");
905 } 928 }
906 929
907 free(cbcmacs);
908
909 if(!valid_key) 930 if(!valid_key)
910 { 931 {
911 if(g_force) 932 if(g_force)
@@ -916,11 +937,9 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
916 937
917 if(getenv("SB_REAL_KEY") != 0) 938 if(getenv("SB_REAL_KEY") != 0)
918 { 939 {
919 struct crypto_key_t k;
920 char *env = getenv("SB_REAL_KEY"); 940 char *env = getenv("SB_REAL_KEY");
921 if(!parse_key(&env, &k) || *env) 941 if(!parse_key(&env, &real_key) || *env)
922 fatal(SB_ERROR, "Invalid SB_REAL_KEY\n"); 942 fatal(SB_ERROR, "Invalid SB_REAL_KEY\n");
923 memcpy(real_key, k.u.key, 16);
924 /* assume the key is valid */ 943 /* assume the key is valid */
925 if(valid_key) 944 if(valid_key)
926 printf(GREY, " Overriding real key\n"); 945 printf(GREY, " Overriding real key\n");
@@ -931,16 +950,17 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
931 950
932 printf(RED, " Summary:\n"); 951 printf(RED, " Summary:\n");
933 printf(GREEN, " Real key: "); 952 printf(GREEN, " Real key: ");
934 print_hex(YELLOW, real_key, 16, true); 953 print_hex(YELLOW, real_key.u.key, 16, true);
935 printf(GREEN, " IV : "); 954 printf(GREEN, " IV : ");
936 print_hex(YELLOW, buf, 16, true); 955 print_hex(YELLOW, buf, 16, true);
937 956
938 memcpy(sb_file->real_key, real_key, 16); 957 memcpy(sb_file->real_key, real_key.u.key, 16);
939 memcpy(sb_file->crypto_iv, buf, 16); 958 memcpy(sb_file->crypto_iv, buf, 16);
959 /* setup real key if needed */
960 check_crypto(crypto_setup(&real_key));
940 } 961 }
941 else 962 else
942 valid_key = true; 963 valid_key = true;
943
944 /* sections */ 964 /* sections */
945 if(!(flags & SB_RAW_MODE)) 965 if(!(flags & SB_RAW_MODE))
946 { 966 {
@@ -986,12 +1006,13 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
986 /* save it */ 1006 /* save it */
987 byte *sec = xmalloc(size); 1007 byte *sec = xmalloc(size);
988 if(encrypted) 1008 if(encrypted)
989 cbc_mac(buf + pos, sec, size / BLOCK_SIZE, real_key, buf, NULL, 0); 1009 check_crypto(crypto_apply(buf + pos, sec, size / BLOCK_SIZE, buf, NULL, false));
990 else 1010 else
991 memcpy(sec, buf + pos, size); 1011 memcpy(sec, buf + pos, size);
992 1012
993 struct sb_section_t *s = read_section(data_sec, sec_hdr->identifier, 1013 struct sb_section_t *s = read_section(data_sec, sec_hdr->identifier,
994 sec, size, " ", u, cprintf, err); 1014 sec, size, " ", u, cprintf, out_err);
1015 free(sec);
995 if(s) 1016 if(s)
996 { 1017 {
997 s->other_flags = sec_hdr->flags & ~SECTION_STD_MASK; 1018 s->other_flags = sec_hdr->flags & ~SECTION_STD_MASK;
@@ -1001,9 +1022,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
1001 free(s); 1022 free(s);
1002 } 1023 }
1003 else 1024 else
1004 fatal(*err, "Error reading section\n"); 1025 fatal(*out_err, "Error reading section\n");
1005
1006 free(sec);
1007 } 1026 }
1008 } 1027 }
1009 else if(valid_key) 1028 else if(valid_key)
@@ -1019,7 +1038,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
1019 memcpy(iv, buf, 16); 1038 memcpy(iv, buf, 16);
1020 byte cmd[BLOCK_SIZE]; 1039 byte cmd[BLOCK_SIZE];
1021 if(sb_header->nr_keys > 0) 1040 if(sb_header->nr_keys > 0)
1022 cbc_mac(buf + offset, cmd, 1, real_key, iv, &iv, 0); 1041 check_crypto(crypto_apply(buf + offset, cmd, 1, iv, &iv, false));
1023 else 1042 else
1024 memcpy(cmd, buf + offset, BLOCK_SIZE); 1043 memcpy(cmd, buf + offset, BLOCK_SIZE);
1025 struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)cmd; 1044 struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)cmd;
@@ -1077,12 +1096,13 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
1077 /* save it */ 1096 /* save it */
1078 byte *sec = xmalloc(size); 1097 byte *sec = xmalloc(size);
1079 if(encrypted) 1098 if(encrypted)
1080 cbc_mac(buf + pos, sec, size / BLOCK_SIZE, real_key, buf, NULL, 0); 1099 check_crypto(crypto_apply(buf + pos, sec, size / BLOCK_SIZE, buf, NULL, false));
1081 else 1100 else
1082 memcpy(sec, buf + pos, size); 1101 memcpy(sec, buf + pos, size);
1083 1102
1084 struct sb_section_t *s = read_section(data_sec, tag->identifier, 1103 struct sb_section_t *s = read_section(data_sec, tag->identifier,
1085 sec, size, " ", u, cprintf, err); 1104 sec, size, " ", u, cprintf, out_err);
1105 free(sec);
1086 if(s) 1106 if(s)
1087 { 1107 {
1088 s->other_flags = tag->flags & ~SECTION_STD_MASK; 1108 s->other_flags = tag->flags & ~SECTION_STD_MASK;
@@ -1094,8 +1114,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
1094 free(s); 1114 free(s);
1095 } 1115 }
1096 else 1116 else
1097 fatal(*err, "Error reading section\n"); 1117 fatal(*out_err, "Error reading section\n");
1098 free(sec);
1099 1118
1100 /* last one ? */ 1119 /* last one ? */
1101 if(tag->hdr.flags & SB_INST_LAST_TAG) 1120 if(tag->hdr.flags & SB_INST_LAST_TAG)
@@ -1126,7 +1145,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
1126 printf(OFF, " "); 1145 printf(OFF, " ");
1127 print_hex(YELLOW, encrypted_block + 16, 16, true); 1146 print_hex(YELLOW, encrypted_block + 16, 16, true);
1128 /* decrypt it */ 1147 /* decrypt it */
1129 cbc_mac(encrypted_block, decrypted_block, 2, real_key, buf, NULL, 0); 1148 check_crypto(crypto_apply(encrypted_block, decrypted_block, 2, buf, NULL, false));
1130 } 1149 }
1131 else 1150 else
1132 memcpy(decrypted_block, &buf[filesize - 32], 32); 1151 memcpy(decrypted_block, &buf[filesize - 32], 32);
@@ -1153,6 +1172,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo
1153 fatal(SB_CHECKSUM_ERROR, "File SHA-1 error\n"); 1172 fatal(SB_CHECKSUM_ERROR, "File SHA-1 error\n");
1154 } 1173 }
1155 1174
1175 free(cbcmacs);
1156 return sb_file; 1176 return sb_file;
1157 #undef printf 1177 #undef printf
1158 #undef fatal 1178 #undef fatal
diff --git a/utils/imxtools/sbtools/sb.h b/utils/imxtools/sbtools/sb.h
index 9ab7fe7aba..62fe4464fb 100644
--- a/utils/imxtools/sbtools/sb.h
+++ b/utils/imxtools/sbtools/sb.h
@@ -232,8 +232,7 @@ enum sb_error_t
232 SB_FORMAT_ERROR = -5, 232 SB_FORMAT_ERROR = -5,
233 SB_CHECKSUM_ERROR = -6, 233 SB_CHECKSUM_ERROR = -6,
234 SB_NO_VALID_KEY = -7, 234 SB_NO_VALID_KEY = -7,
235 SB_FIRST_CRYPTO_ERROR = -8, 235 SB_CRYPTO_ERROR = -8,
236 SB_LAST_CRYPTO_ERROR = SB_FIRST_CRYPTO_ERROR - CRYPTO_NUM_ERRORS,
237}; 236};
238 237
239#define SB_RAW_MODE (1 << 0) /* read image in raw mode (aka bootloader-like) */ 238#define SB_RAW_MODE (1 << 0) /* read image in raw mode (aka bootloader-like) */
diff --git a/utils/imxtools/sbtools/sb1.h b/utils/imxtools/sbtools/sb1.h
index f2dec509b7..dd2f8afeec 100644
--- a/utils/imxtools/sbtools/sb1.h
+++ b/utils/imxtools/sbtools/sb1.h
@@ -139,8 +139,7 @@ enum sb1_error_t
139 SB1_FORMAT_ERROR = -5, 139 SB1_FORMAT_ERROR = -5,
140 SB1_CHECKSUM_ERROR = -6, 140 SB1_CHECKSUM_ERROR = -6,
141 SB1_NO_VALID_KEY = -7, 141 SB1_NO_VALID_KEY = -7,
142 SB1_FIRST_CRYPTO_ERROR = -8, 142 SB1_CRYPTO_ERROR = -8,
143 SB1_LAST_CRYPTO_ERROR = SB1_FIRST_CRYPTO_ERROR - CRYPTO_NUM_ERRORS,
144}; 143};
145 144
146enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename); 145enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename);