1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Amaury Pouly
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 static enum crypto_method_t cur_method
= CRYPTO_NONE
;
31 static union xorcrypt_key_t xor_key
[2];
32 static uint16_t usb_vid
, usb_pid
;
34 void crypto_setup(enum crypto_method_t method
, void *param
)
40 memcpy(key
, param
, sizeof(key
));
44 uint32_t value
= *(uint32_t *)param
;
45 usb_vid
= value
>> 16;
46 usb_pid
= value
& 0xffff;
55 byte
*in_data
, /* Input data */
56 byte
*out_data
, /* Output data (or NULL) */
57 int nr_blocks
, /* Number of blocks (one block=16 bytes) */
58 byte iv
[16], /* Key */
59 byte (*out_cbc_mac
)[16], /* CBC-MAC of the result (or NULL) */
62 if(cur_method
== CRYPTO_KEY
)
64 cbc_mac(in_data
, out_data
, nr_blocks
, key
, iv
, out_cbc_mac
, encrypt
);
65 return CRYPTO_ERROR_SUCCESS
;
68 else if(cur_method
== CRYPTO_USBOTP
)
70 if(out_cbc_mac
&& !encrypt
)
71 memcpy(*out_cbc_mac
, in_data
+ 16 * (nr_blocks
- 1), 16);
73 libusb_device_handle
*handle
= NULL
;
77 libusb_set_debug(NULL
,3);
79 handle
= libusb_open_device_with_vid_pid(ctx
, usb_vid
, usb_pid
);
82 printf("usbotp: cannot open device %04x:%04x\n", usb_vid
, usb_pid
);
83 return CRYPTO_ERROR_NODEVICE
;
85 /* get device pointer */
86 libusb_device
*mydev
= libusb_get_device(handle
);
88 printf("usbotp: device found at %d:%d\n", libusb_get_bus_number(mydev
),
89 libusb_get_device_address(mydev
));
91 /* explore configuration */
92 libusb_get_configuration(handle
, &config_id
);
93 struct libusb_config_descriptor
*config
;
94 libusb_get_active_config_descriptor(mydev
, &config
);
98 printf("usbotp: configuration: %d\n", config_id
);
99 printf("usbotp: interfaces: %d\n", config
->bNumInterfaces
);
102 const struct libusb_endpoint_descriptor
*endp
= NULL
;
104 for(intf
= 0; intf
< config
->bNumInterfaces
; intf
++)
105 for(intf_alt
= 0; intf_alt
< config
->interface
[intf
].num_altsetting
; intf_alt
++)
106 for(int ep
= 0; ep
< config
->interface
[intf
].altsetting
[intf_alt
].bNumEndpoints
; ep
++)
108 endp
= &config
->interface
[intf
].altsetting
[intf_alt
].endpoint
[ep
];
109 if((endp
->bmAttributes
& LIBUSB_TRANSFER_TYPE_MASK
) == LIBUSB_TRANSFER_TYPE_INTERRUPT
&&
110 (endp
->bEndpointAddress
& LIBUSB_ENDPOINT_DIR_MASK
) == LIBUSB_ENDPOINT_IN
)
113 libusb_close(handle
);
114 printf("usbotp: No suitable endpoint found\n");
115 return CRYPTO_ERROR_BADENDP
;
119 printf("usbotp: use interface %d, alt %d\n", intf
, intf_alt
);
120 printf("usbotp: use endpoint %d\n", endp
->bEndpointAddress
);
123 if(libusb_claim_interface(handle
, intf
) != 0)
126 printf("usbotp: claim error\n");
127 return CRYPTO_ERROR_CLAIMFAIL
;
130 int buffer_size
= 16 + 16 * nr_blocks
;
131 unsigned char *buffer
= xmalloc(buffer_size
);
132 memcpy(buffer
, iv
, 16);
133 memcpy(buffer
+ 16, in_data
, 16 * nr_blocks
);
134 int ret
= libusb_control_transfer(handle
,
135 LIBUSB_REQUEST_TYPE_CLASS
| LIBUSB_RECIPIENT_DEVICE
,
136 0xaa, encrypt
? 0xeeee : 0xdddd, 0, buffer
, buffer_size
, 1000);
140 printf("usbotp: control transfer failed: %d\n", ret
);
141 libusb_release_interface(handle
, intf
);
142 libusb_close(handle
);
143 return CRYPTO_ERROR_DEVREJECT
;
147 ret
= libusb_interrupt_transfer(handle
, endp
->bEndpointAddress
, buffer
,
148 buffer_size
, &recv_size
, 1000);
149 libusb_release_interface(handle
, intf
);
150 libusb_close(handle
);
155 printf("usbotp: interrupt transfer failed: %d\n", ret
);
156 return CRYPTO_ERROR_DEVSILENT
;
158 if(recv_size
!= buffer_size
)
161 printf("usbotp: device returned %d bytes, expected %d\n", recv_size
,
163 return CRYPTO_ERROR_DEVERR
;
167 memcpy(out_data
, buffer
+ 16, 16 * nr_blocks
);
168 if(out_cbc_mac
&& encrypt
)
169 memcpy(*out_cbc_mac
, buffer
+ buffer_size
- 16, 16);
171 return CRYPTO_ERROR_SUCCESS
;
175 return CRYPTO_ERROR_BADSETUP
;
179 byte
*in_data
, /* Input data */
180 byte
*out_data
, /* Output data (or NULL) */
181 int nr_blocks
, /* Number of blocks (one block=16 bytes) */
182 struct crypto_key_t
*key
, /* Key */
183 byte iv
[16], /* IV */
184 byte (*out_cbc_mac
)[16], /* CBC-MAC of the result (or NULL) */
187 crypto_setup(key
->method
, (void *)key
->u
.param
);
188 return crypto_apply(in_data
, out_data
, nr_blocks
, iv
, out_cbc_mac
, encrypt
);