diff options
Diffstat (limited to 'utils')
-rw-r--r-- | utils/imxtools/sbtools/Makefile | 11 | ||||
-rw-r--r-- | utils/imxtools/sbtools/crypto.c | 188 | ||||
-rw-r--r-- | utils/imxtools/sbtools/crypto.cpp | 55 | ||||
-rw-r--r-- | utils/imxtools/sbtools/crypto.h | 49 | ||||
-rw-r--r-- | utils/imxtools/sbtools/misc.c | 29 | ||||
-rw-r--r-- | utils/imxtools/sbtools/rsrc.h | 3 | ||||
-rw-r--r-- | utils/imxtools/sbtools/sb.c | 148 | ||||
-rw-r--r-- | utils/imxtools/sbtools/sb.h | 3 | ||||
-rw-r--r-- | utils/imxtools/sbtools/sb1.h | 3 |
9 files changed, 171 insertions, 318 deletions
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 @@ | |||
1 | DEFINES=-DCRYPTO_LIBUSB | 1 | DEFINES= |
2 | CC=gcc | 2 | CC=gcc |
3 | LD=gcc | 3 | CXX=g++ |
4 | CFLAGS=-O3 -g -std=c99 -W -Wall `pkg-config --cflags libusb-1.0` $(DEFINES) | 4 | LD=g++ |
5 | CFLAGS=-O3 -g -std=c99 -Wall `pkg-config --cflags libusb-1.0` $(DEFINES) | ||
6 | CXXFLAGS=-O3 -g -Wall $(DEFINES) | ||
5 | LDFLAGS=`pkg-config --libs libusb-1.0` | 7 | LDFLAGS=`pkg-config --libs libusb-1.0` |
6 | BINS=elftosb sbtoelf sbloader rsrctool elftosb1 | 8 | BINS=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 | |||
13 | sbtoelf: sbtoelf.o crc.o crypto.o aes128.o sha1.o xorcrypt.o dbparser.o elf.o misc.o sb.o sb1.o | 18 | sbtoelf: 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 | |||
29 | static enum crypto_method_t cur_method = CRYPTO_NONE; | ||
30 | static byte key[16]; | ||
31 | static uint16_t usb_vid, usb_pid; | ||
32 | |||
33 | void 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 | |||
53 | int 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 | |||
177 | int 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 | |||
24 | static enum crypto_method_t g_cur_method = CRYPTO_NONE; | ||
25 | static byte g_key[16]; | ||
26 | |||
27 | int 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 | |||
40 | int 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 | ||
30 | extern "C" { | ||
31 | #endif | ||
27 | 32 | ||
28 | typedef uint8_t byte; | 33 | typedef 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 */ | ||
57 | void 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 */ | ||
69 | int 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 | |||
77 | union xorcrypt_key_t | 58 | union 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 | ||
96 | int 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 */ | ||
81 | int crypto_setup(struct crypto_key_t *key); | ||
82 | |||
83 | /* return 0 on success, <0 on error */ | ||
84 | int 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 */ |
106 | uint32_t crc(byte *data, int size); | 93 | uint32_t crc(byte *data, int size); |
@@ -127,4 +114,8 @@ uint32_t xor_encrypt(union xorcrypt_key_t keys[2], void *data, int size); | |||
127 | uint32_t xor_decrypt(union xorcrypt_key_t keys[2], void *data, int size); | 114 | uint32_t xor_decrypt(union xorcrypt_key_t keys[2], void *data, int size); |
128 | void xor_generate_key(uint32_t laserfuse[3], union xorcrypt_key_t key[2]); | 115 | void 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 | ||
180 | void add_keys(key_array_t ka, int kac) | 156 | void 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 | ||
80 | enum rsrc_error_t rsrc_write_file(struct rsrc_file_t *rsrc, const char *filename); | 79 | enum 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 | ||
714 | struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, void *u, | 739 | struct 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 | ||
146 | enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename); | 145 | enum sb1_error_t sb1_write_file(struct sb1_file_t *sb, const char *filename); |