summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools/crypto.c
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 /utils/imxtools/sbtools/crypto.c
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
Diffstat (limited to 'utils/imxtools/sbtools/crypto.c')
-rw-r--r--utils/imxtools/sbtools/crypto.c188
1 files changed, 0 insertions, 188 deletions
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}