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 uint16_t usb_vid
, usb_pid
;
33 void crypto_setup(enum crypto_method_t method
, void *param
)
39 memcpy(key
, param
, sizeof(key
));
43 uint32_t value
= *(uint32_t *)param
;
44 usb_vid
= value
>> 16;
45 usb_pid
= value
& 0xffff;
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) */
61 if(cur_method
== CRYPTO_KEY
)
63 cbc_mac(in_data
, out_data
, nr_blocks
, key
, iv
, out_cbc_mac
, encrypt
);
64 return CRYPTO_ERROR_SUCCESS
;
67 else if(cur_method
== CRYPTO_USBOTP
)
69 if(out_cbc_mac
&& !encrypt
)
70 memcpy(*out_cbc_mac
, in_data
+ 16 * (nr_blocks
- 1), 16);
72 libusb_device_handle
*handle
= NULL
;
76 libusb_set_debug(NULL
,3);
78 handle
= libusb_open_device_with_vid_pid(ctx
, usb_vid
, usb_pid
);
81 printf("usbotp: cannot open device %04x:%04x\n", usb_vid
, usb_pid
);
82 return CRYPTO_ERROR_NODEVICE
;
84 /* get device pointer */
85 libusb_device
*mydev
= libusb_get_device(handle
);
87 printf("usbotp: device found at %d:%d\n", libusb_get_bus_number(mydev
),
88 libusb_get_device_address(mydev
));
90 /* explore configuration */
91 libusb_get_configuration(handle
, &config_id
);
92 struct libusb_config_descriptor
*config
;
93 libusb_get_active_config_descriptor(mydev
, &config
);
97 printf("usbotp: configuration: %d\n", config_id
);
98 printf("usbotp: interfaces: %d\n", config
->bNumInterfaces
);
101 const struct libusb_endpoint_descriptor
*endp
= NULL
;
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
++)
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
)
112 libusb_close(handle
);
113 printf("usbotp: No suitable endpoint found\n");
114 return CRYPTO_ERROR_BADENDP
;
118 printf("usbotp: use interface %d, alt %d\n", intf
, intf_alt
);
119 printf("usbotp: use endpoint %d\n", endp
->bEndpointAddress
);
122 if(libusb_claim_interface(handle
, intf
) != 0)
125 printf("usbotp: claim error\n");
126 return CRYPTO_ERROR_CLAIMFAIL
;
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);
139 printf("usbotp: control transfer failed: %d\n", ret
);
140 libusb_release_interface(handle
, intf
);
141 libusb_close(handle
);
142 return CRYPTO_ERROR_DEVREJECT
;
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
);
154 printf("usbotp: interrupt transfer failed: %d\n", ret
);
155 return CRYPTO_ERROR_DEVSILENT
;
157 if(recv_size
!= buffer_size
)
160 printf("usbotp: device returned %d bytes, expected %d\n", recv_size
,
162 return CRYPTO_ERROR_DEVERR
;
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);
170 return CRYPTO_ERROR_SUCCESS
;
174 return CRYPTO_ERROR_BADSETUP
;
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) */
186 crypto_setup(key
->method
, (void *)key
->u
.param
);
187 return crypto_apply(in_data
, out_data
, nr_blocks
, iv
, out_cbc_mac
, encrypt
);