summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);