iPXE
iphone.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <string.h>
29#include <stdio.h>
30#include <errno.h>
31#include <ipxe/netdevice.h>
32#include <ipxe/ethernet.h>
33#include <ipxe/if_ether.h>
34#include <ipxe/profile.h>
35#include <ipxe/base64.h>
36#include <ipxe/sha256.h>
37#include <ipxe/rsa.h>
38#include <ipxe/x509.h>
39#include <ipxe/pem.h>
40#include <ipxe/xfer.h>
41#include <ipxe/tls.h>
42#include <ipxe/usb.h>
43#include "iphone.h"
44
45/** @file
46 *
47 * iPhone USB Ethernet driver
48 *
49 */
50
51/* Disambiguate the various error causes */
52#define EPIPE_NO_MUX __einfo_error ( EINFO_EPIPE_NO_MUX )
53#define EINFO_EPIPE_NO_MUX \
54 __einfo_uniqify ( EINFO_EPIPE, 0x01, \
55 "No USB multiplexer" )
56#define EINPROGRESS_PAIRING __einfo_error ( EINFO_EINPROGRESS_PAIRING )
57#define EINFO_EINPROGRESS_PAIRING \
58 __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, \
59 "Pairing in progress" )
60#define ENOTCONN_DISABLED __einfo_error ( EINFO_ENOTCONN_DISABLED )
61#define EINFO_ENOTCONN_DISABLED \
62 __einfo_uniqify ( EINFO_ENOTCONN, IPHONE_LINK_DISABLED, \
63 "Personal Hotspot disabled" )
64#define ENOTCONN_STATUS( status ) \
65 EUNIQ ( EINFO_ENOTCONN, ( (status) & 0x1f ), \
66 ENOTCONN_DISABLED )
67
68static int ipair_create ( struct interface *xfer, unsigned int flags );
69
70/** Bulk IN completion profiler */
71static struct profiler iphone_in_profiler __profiler =
72 { .name = "iphone.in" };
73
74/** Bulk OUT profiler */
75static struct profiler iphone_out_profiler __profiler =
76 { .name = "iphone.out" };
77
78/** List of USB multiplexers */
79static LIST_HEAD ( imuxes );
80
81/** List of iPhone network devices */
82static LIST_HEAD ( iphones );
83
84/******************************************************************************
85 *
86 * iPhone pairing certificates
87 *
88 ******************************************************************************
89 */
90
91/** iPhone root certificate fingerprint */
93
94/** Root of trust for iPhone certificates */
95static struct x509_root icert_root = {
96 .refcnt = REF_INIT ( ref_no_free ),
97 .digest = &sha256_algorithm,
98 .count = 1,
99 .fingerprints = icert_root_fingerprint,
100};
101
102/** Single zero byte used in constructed certificates */
103static const uint8_t icert_nul[] = { 0x00 };
104
105/** "RSA algorithm" identifier used in constructed certificates */
106static const uint8_t icert_rsa[] = {
107 /* algorithm */
110 ASN1_NULL, 0x00 )
111};
112
113/** "SHA-256 with RSA algorithm" identifier used in constructed certificates */
119
120/** Extensions used in constructed root certificate */
122 /* extensions */
124 /* basicConstraints */
126 /* extnID */
128 /* critical */
129 ASN1_SHORT ( ASN1_BOOLEAN, 0xff ),
130 /* extnValue */
134 0xff ) ) ) ) ) )
135};
136
137/** Extensions used in constructed root certificate */
140
141/** Extensions used in constructed leaf certificates */
143 /* extensions */
145 /* basicConstraints */
147 /* extnID */
149 /* critical */
150 ASN1_SHORT ( ASN1_BOOLEAN, 0xff ),
151 /* extnValue */
155 0x00 ) ) ) ),
156 /* keyUsage */
158 /* extnID */
160 /* critical */
161 ASN1_SHORT ( ASN1_BOOLEAN, 0xff ),
162 /* extnValue */
167 0x00 ) ) ) ) )
168};
169
170/** Extensions used in constructed leaf certificates */
173
174/** "TBSCertificate" prefix in constructed certificates */
175static const uint8_t icert_tbs_prefix[] = {
176 /* version */
178 /* serialNumber */
180 /* signature */
183 ASN1_NULL, 0x00 )
184};
185
186/** Validity period in constructed certificates */
187static const uint8_t icert_validity[] = {
188 /* validity */
190 /* notBefore */
192 '1', '9', '7', '8', '1', '2', '1', '0',
193 '2', '2', '0', '0', '0', '0', 'Z' ),
194 /* notAfter */
196 '2', '9', '9', '9', '0', '1', '0', '1',
197 '0', '0', '0', '0', '0', '0', 'Z' ) )
198};
199
200/** "Root" subject name */
207
208/** "Root" subject name */
211
212/** "iPXE" subject name */
219
220/** "iPXE" subject name */
223
224/** "iPhone" subject name */
230 'i', 'P', 'h', 'o', 'n', 'e' ) ) ) )
231};
232
233/** "iPhone" subject name */
236
237/** Public key(s) used for pairing */
238static const uint8_t icert_public_a[] __unused = {
239 0x02, 0x81, 0x81, 0x00, 0xc9, 0xc0, 0xdd, 0xa6, 0xd5, 0xf9, 0x05, 0x3e,
240 0x1d, 0xcb, 0x67, 0x08, 0xa8, 0x50, 0x27, 0x63, 0x95, 0x87, 0x42, 0x7e,
241 0xfb, 0xff, 0x55, 0x55, 0xb8, 0xc0, 0x6f, 0x13, 0xcb, 0xf7, 0xc5, 0x1b,
242 0xda, 0x44, 0x3c, 0xbc, 0x1a, 0xe1, 0x15, 0x1e, 0xab, 0x56, 0x74, 0x02,
243 0x8b, 0xb3, 0xcd, 0x42, 0x56, 0xcd, 0x9c, 0xc3, 0x15, 0xe2, 0x33, 0x97,
244 0x6d, 0x77, 0xdd, 0x20, 0x3a, 0x74, 0xb1, 0x4c, 0xee, 0xeb, 0xe8, 0xaa,
245 0x20, 0x71, 0x5a, 0xa2, 0x5b, 0xf8, 0x1a, 0xcb, 0xd2, 0x7b, 0x96, 0xb6,
246 0x42, 0xb4, 0x7c, 0x7a, 0x13, 0xec, 0x55, 0xd3, 0x36, 0x8b, 0xe3, 0x17,
247 0xc5, 0xc4, 0xcc, 0xe0, 0x27, 0x8c, 0xed, 0xa1, 0x4c, 0x8a, 0x50, 0x4a,
248 0x1c, 0xc4, 0x58, 0xf6, 0xcd, 0xcc, 0xc3, 0x5f, 0xe6, 0x3c, 0xff, 0x97,
249 0x51, 0xed, 0xf5, 0xaa, 0x89, 0xcc, 0x3f, 0x63, 0x67, 0x46, 0x9f, 0xbf,
250 0x02, 0x03, 0x01, 0x00, 0x01
251};
252static const uint8_t icert_public_b[] __unused = {
253 0x02, 0x81, 0x81, 0x00, 0xcd, 0x96, 0x81, 0x78, 0xbb, 0x2e, 0x64, 0xda,
254 0xd3, 0x7e, 0xd7, 0x3a, 0xac, 0x3f, 0x00, 0xe5, 0x41, 0x65, 0x56, 0xac,
255 0x2d, 0x77, 0xc0, 0x1a, 0xad, 0x32, 0xca, 0x0c, 0x72, 0xae, 0xdb, 0x57,
256 0xc1, 0xc7, 0x79, 0xef, 0xc6, 0x71, 0x9f, 0xad, 0x82, 0x14, 0x94, 0x4b,
257 0xf9, 0xd8, 0x78, 0xf1, 0xca, 0x99, 0xf5, 0x71, 0x07, 0x88, 0xd7, 0x55,
258 0xc7, 0xcb, 0x36, 0x5d, 0xdb, 0x84, 0x46, 0xac, 0x05, 0xea, 0xf1, 0xe1,
259 0xbe, 0x91, 0x50, 0x85, 0x1e, 0x64, 0xab, 0x02, 0x82, 0xab, 0xba, 0x42,
260 0x06, 0x5a, 0xe3, 0xc3, 0x25, 0xd0, 0x95, 0x04, 0x54, 0xb4, 0x44, 0x40,
261 0x5a, 0x42, 0x06, 0x04, 0x7d, 0x3b, 0x9e, 0xaf, 0x2e, 0xe9, 0xc8, 0xad,
262 0x46, 0x3a, 0xff, 0xe2, 0x39, 0xc8, 0x48, 0x0a, 0x49, 0xaa, 0xfe, 0x1f,
263 0x6c, 0x91, 0x5d, 0x1d, 0xd6, 0xb0, 0x04, 0xd1, 0x6c, 0xb2, 0x43, 0xaf,
264 0x02, 0x03, 0x01, 0x00, 0x01
265};
266
267/**
268 * "Private" key(s) used for pairing
269 *
270 * Yes, this publicly visible "private" key completely obviates any
271 * nominal security provided by the pairing process. Looked at
272 * another way, this modifies the iPhone to behave like every other
273 * USB tethering device: if the cable is physically connected and
274 * tethering is enabled then the device will Just Work.
275 *
276 * Unlike Android, the iPhone seems to have no meaningful permissions
277 * model: any device that is trusted to use the phone for tethering
278 * seems to also be trusted to use the iPhone for any other purpose
279 * (e.g. accessing files, reading messages, etc). Apple should
280 * probably fix this at some point, e.g. via defining extended key
281 * usages in the root and host certificates.
282 */
283static const uint8_t icert_private_a[] __unused = {
284 0x02, 0x81, 0x80, 0x1d, 0x60, 0xb7, 0x25, 0xdf, 0x0c, 0x76, 0xc5, 0xf7,
285 0xc2, 0xb1, 0x8b, 0x22, 0x2f, 0x21, 0xbd, 0x2f, 0x7d, 0xd5, 0xa1, 0xf6,
286 0x01, 0xd5, 0x24, 0x39, 0x55, 0xd4, 0x16, 0xd6, 0xe1, 0x8a, 0x53, 0x26,
287 0xf2, 0x3e, 0xc1, 0xc9, 0x4c, 0x33, 0x2e, 0x17, 0x16, 0xec, 0xa7, 0x9e,
288 0x3e, 0x1d, 0x4a, 0x66, 0xa7, 0x64, 0x07, 0x48, 0x3d, 0x7a, 0xf3, 0xb6,
289 0xdd, 0xf8, 0x56, 0x04, 0x0d, 0x0f, 0xef, 0xf8, 0xbd, 0xbc, 0x73, 0xe2,
290 0xc2, 0xae, 0x1b, 0x87, 0x90, 0x18, 0x2a, 0x68, 0xff, 0xae, 0x49, 0xdf,
291 0x7c, 0xff, 0xe8, 0x44, 0xa8, 0x3e, 0x4e, 0x4f, 0xf5, 0xfa, 0x51, 0x96,
292 0xb8, 0x08, 0xf3, 0x18, 0xd6, 0x52, 0xdf, 0x3a, 0x8a, 0xed, 0xda, 0xcd,
293 0xb4, 0x06, 0x99, 0x41, 0xcb, 0x23, 0x17, 0xaf, 0xc3, 0x3e, 0xfe, 0xdf,
294 0x97, 0xf3, 0xd6, 0x18, 0x7e, 0x03, 0xaf, 0x62, 0xb2, 0xc8, 0xc9
295};
296static const uint8_t icert_private_b[] __unused = {
297 0x02, 0x81, 0x80, 0x45, 0xbd, 0xc0, 0xbe, 0x0c, 0x01, 0x79, 0x05, 0x22,
298 0xa9, 0xec, 0xa9, 0x62, 0xb5, 0x1c, 0xc0, 0xa8, 0xa6, 0x8f, 0xf8, 0x68,
299 0x94, 0x2e, 0xfe, 0xdd, 0xb2, 0x55, 0x08, 0x53, 0xff, 0x2d, 0x39, 0x5f,
300 0xeb, 0x23, 0x5a, 0x4b, 0x9f, 0x4f, 0xe3, 0xb4, 0x34, 0xf6, 0xf9, 0xaf,
301 0x0f, 0xd8, 0x37, 0x6d, 0xdb, 0x3c, 0x7f, 0xd3, 0x66, 0x80, 0x66, 0x01,
302 0x18, 0xd6, 0xa0, 0x90, 0x4f, 0x17, 0x09, 0xb8, 0x68, 0x44, 0xf0, 0xde,
303 0x16, 0x4a, 0x8a, 0x0d, 0xa7, 0x5f, 0xb5, 0x4c, 0x53, 0xcc, 0x21, 0xdd,
304 0x4f, 0x05, 0x64, 0xa5, 0xc5, 0xac, 0x2c, 0xd8, 0x0a, 0x7b, 0xf5, 0xa4,
305 0x63, 0x32, 0xb0, 0x2c, 0xf8, 0xef, 0x8c, 0xf8, 0x2c, 0xba, 0x1c, 0x2c,
306 0xc7, 0x0a, 0xf3, 0xe9, 0x8f, 0xfb, 0x0a, 0x61, 0x1b, 0x3a, 0xdd, 0x9f,
307 0x74, 0x7d, 0xb3, 0x42, 0x59, 0x52, 0x07, 0x59, 0x8e, 0xb7, 0x41
308};
309
310/** Key pair selection
311 *
312 * This exists only to allow for testing of the process for handling a
313 * failed TLS negotiation.
314 */
315#define icert_key_suffix a
316#define icert_key_variable( prefix ) _C2 ( prefix, icert_key_suffix )
317#define icert_public icert_key_variable ( icert_public_ )
318#define icert_private icert_key_variable ( icert_private_ )
319
320/** PEM certificate prefix */
321static const char icert_begin[] = "-----BEGIN CERTIFICATE-----\n";
322
323/** PEM certificate suffix */
324static const char icert_end[] = "\n-----END CERTIFICATE-----\n";
325
326/**
327 * Free pairing certificates
328 *
329 * @v icert Pairing certificates
330 */
331static void icert_free ( struct icert *icert ) {
332
333 privkey_put ( icert->key );
334 x509_put ( icert->root );
335 x509_put ( icert->host );
336 x509_put ( icert->device );
337 memset ( icert, 0, sizeof ( *icert ) );
338}
339
340/**
341 * Construct certificate
342 *
343 * @v icert Pairing certificates
344 * @v subject Subject name
345 * @v issuer Issuer name
346 * @v private Private key
347 * @v public Public key
348 * @v exts Certificate extensions
349 * @v cert Certificate to fill in
350 * @ret rc Return status code
351 *
352 * On success, the caller is responsible for eventually calling
353 * x509_put() on the allocated encoded certificate.
354 */
355static int icert_cert ( struct icert *icert, struct asn1_cursor *subject,
356 struct asn1_cursor *issuer, struct asn1_cursor *private,
357 struct asn1_cursor *public, struct asn1_cursor *exts,
358 struct x509_certificate **cert ) {
359 struct digest_algorithm *digest = &sha256_algorithm;
360 struct pubkey_algorithm *pubkey = &rsa_algorithm;
361 struct asn1_builder spki = { NULL, 0 };
362 struct asn1_builder tbs = { NULL, 0 };
363 struct asn1_builder raw = { NULL, 0 };
364 uint8_t digest_ctx[SHA256_CTX_SIZE];
365 uint8_t digest_out[SHA256_DIGEST_SIZE];
366 int rc;
367
368 /* Construct subjectPublicKeyInfo */
369 if ( ( rc = ( asn1_prepend_raw ( &spki, public->data, public->len ),
371 sizeof ( icert_nul ) ),
372 asn1_wrap ( &spki, ASN1_BIT_STRING ),
374 sizeof ( icert_rsa ) ),
375 asn1_wrap ( &spki, ASN1_SEQUENCE ) ) ) != 0 ) {
376 DBGC ( icert, "ICERT %p could not build subjectPublicKeyInfo: "
377 "%s\n", icert, strerror ( rc ) );
378 goto err_spki;
379 }
380
381 /* Construct tbsCertificate */
382 if ( ( rc = ( asn1_prepend_raw ( &tbs, exts->data, exts->len ),
383 asn1_prepend_raw ( &tbs, spki.data, spki.len ),
384 asn1_prepend_raw ( &tbs, subject->data, subject->len ),
386 sizeof ( icert_validity ) ),
387 asn1_prepend_raw ( &tbs, issuer->data, issuer->len ),
389 sizeof ( icert_tbs_prefix ) ),
390 asn1_wrap ( &tbs, ASN1_SEQUENCE ) ) ) != 0 ) {
391 DBGC ( icert, "ICERT %p could not build tbsCertificate: %s\n",
392 icert, strerror ( rc ) );
393 goto err_tbs;
394 }
395
396 /* Calculate certificate digest */
397 digest_init ( digest, digest_ctx );
398 digest_update ( digest, digest_ctx, tbs.data, tbs.len );
399 digest_final ( digest, digest_ctx, digest_out );
400
401 /* Construct signature using "private" key */
402 if ( ( rc = pubkey_sign ( pubkey, private, digest, digest_out,
403 &raw ) ) != 0 ) {
404 DBGC ( icert, "ICERT %p could not sign: %s\n",
405 icert, strerror ( rc ) );
406 goto err_pubkey_sign;
407 }
408
409 /* Construct raw certificate data */
410 if ( ( rc = ( asn1_prepend_raw ( &raw, icert_nul,
411 sizeof ( icert_nul ) ),
414 sizeof ( icert_sha256_rsa ) ),
415 asn1_prepend_raw ( &raw, tbs.data, tbs.len ),
416 asn1_wrap ( &raw, ASN1_SEQUENCE ) ) ) != 0 ) {
417 DBGC ( icert, "ICERT %p could not build certificate: %s\n",
418 icert, strerror ( rc ) );
419 goto err_raw;
420 }
421
422 /* Parse certificate */
423 if ( ( rc = x509_certificate ( raw.data, raw.len, cert ) ) != 0 ) {
424 DBGC ( icert, "ICERT %p invalid certificate: %s\n",
425 icert, strerror ( rc ) );
426 DBGC_HDA ( icert, 0, raw.data, raw.len );
427 goto err_x509;
428 }
429
430 err_x509:
431 err_raw:
432 err_pubkey_sign:
433 err_tbs:
434 err_spki:
435 free ( raw.data );
436 free ( tbs.data );
437 free ( spki.data );
438 return rc;
439}
440
441/**
442 * Construct certificates
443 *
444 * @v icert Certificate set
445 * @v pubkey Device public key
446 * @ret rc Return status code
447 */
448static int icert_certs ( struct icert *icert, struct asn1_cursor *key ) {
449 struct digest_algorithm *digest = icert_root.digest;
450 struct asn1_builder public = { NULL, 0 };
451 struct asn1_builder *private;
452 int rc;
453
454 /* Free any existing key and certificates */
455 icert_free ( icert );
456
457 /* Allocate "private" key */
458 icert->key = zalloc ( sizeof ( *icert->key ) );
459 if ( ! icert->key ) {
460 rc = -ENOMEM;
461 goto error;
462 }
464 private = &icert->key->builder;
465
466 /* Construct our "private" key */
467 if ( ( rc = ( asn1_prepend_raw ( private, icert_private,
468 sizeof ( icert_private ) ),
470 sizeof ( icert_public ) ),
472 sizeof ( icert_nul ) ),
473 asn1_wrap ( private, ASN1_SEQUENCE ) ) ) != 0 ) {
474 DBGC ( icert, "ICERT %p could not build private key: %s\n",
475 icert, strerror ( rc ) );
476 goto error;
477 }
478
479 /* Construct our own public key */
480 if ( ( rc = ( asn1_prepend_raw ( &public, icert_public,
481 sizeof ( icert_public ) ),
482 asn1_wrap ( &public, ASN1_SEQUENCE ) ) ) != 0 ) {
483 DBGC ( icert, "ICERT %p could not build public key: %s\n",
484 icert, strerror ( rc ) );
485 goto error;
486 }
487
488 /* Construct root certificate */
490 asn1_built ( private ), asn1_built ( &public ),
491 &icert_root_exts, &icert->root ) ) != 0 )
492 goto error;
493
494 /* Construct host certificate */
496 asn1_built ( private ), asn1_built ( &public ),
497 &icert_leaf_exts, &icert->host ) ) != 0 )
498 goto error;
499
500 /* Construct device certificate */
502 asn1_built ( private ), key,
503 &icert_leaf_exts, &icert->device ) ) != 0 )
504 goto error;
505
506 /* Construct root of trust */
507 assert ( digest->digestsize == sizeof ( icert_root_fingerprint ) );
509
510 /* Free constructed keys */
511 free ( public.data );
512 return 0;
513
514 error:
515 icert_free ( icert );
516 free ( public.data );
517 return rc;
518}
519
520/**
521 * Construct doubly base64-encoded certificate
522 *
523 * @v icert Pairing certificates
524 * @v cert X.509 certificate
525 * @v encenc Doubly base64-encoded certificate to construct
526 * @ret rc Return status code
527 *
528 * On success, the caller is responsible for eventually calling free()
529 * on the allocated doubly encoded encoded certificate.
530 */
531static int icert_encode ( struct icert *icert, struct x509_certificate *cert,
532 char **encenc ) {
533 size_t encencoded_len;
534 size_t encoded_len;
535 size_t pem_len;
536 char *pem;
537 int rc;
538
539 /* Sanity check */
540 assert ( cert != NULL );
541
542 /* Create PEM */
543 encoded_len = ( base64_encoded_len ( cert->raw.len ) + 1 /* NUL */ );
544 pem_len = ( ( sizeof ( icert_begin ) - 1 /* NUL */ ) +
545 ( encoded_len - 1 /* NUL */ ) +
546 ( sizeof ( icert_end ) - 1 /* NUL */ ) +
547 1 /* NUL */ );
548 pem = malloc ( pem_len );
549 if ( ! pem ) {
550 rc = -ENOMEM;
551 goto err_alloc_pem;
552 }
553 strcpy ( pem, icert_begin );
554 base64_encode ( cert->raw.data, cert->raw.len,
555 ( pem + sizeof ( icert_begin ) - 1 /* NUL */ ),
556 encoded_len );
557 strcpy ( ( pem +
558 ( sizeof ( icert_begin ) - 1 /* NUL */ ) +
559 ( encoded_len - 1 /* NUL */ ) ), icert_end );
560 DBGC2 ( icert, "ICERT %p \"%s\" certificate:\n%s",
561 icert, x509_name ( cert ), pem );
562
563 /* Base64-encode the PEM (sic) */
564 encencoded_len = ( base64_encoded_len ( pem_len - 1 /* NUL */ )
565 + 1 /* NUL */ );
566 *encenc = malloc ( encencoded_len );
567 if ( ! *encenc ) {
568 rc = -ENOMEM;
569 goto err_alloc_encenc;
570 }
571 base64_encode ( pem, ( pem_len - 1 /* NUL */ ), *encenc,
572 encencoded_len );
573
574 /* Success */
575 rc = 0;
576
577 err_alloc_encenc:
578 free ( pem );
579 err_alloc_pem:
580 return rc;
581}
582
583/******************************************************************************
584 *
585 * iPhone USB multiplexer
586 *
587 ******************************************************************************
588 *
589 * The iPhone USB multiplexer speaks a protocol that is almost, but
590 * not quite, entirely unlike TCP.
591 *
592 */
593
594/**
595 * Transmit message
596 *
597 * @v imux USB multiplexer
598 * @v iobuf I/O buffer
599 * @ret rc Return status code
600 */
601static int imux_tx ( struct imux *imux, struct io_buffer *iobuf ) {
602 struct imux_header *hdr = iobuf->data;
603 size_t len = iob_len ( iobuf );
604 int rc;
605
606 /* Populate header */
607 assert ( len >= sizeof ( *hdr ) );
608 hdr->len = htonl ( len );
609 hdr->in_seq = htons ( imux->in_seq );
610 hdr->out_seq = htons ( imux->out_seq );
611 DBGCP ( imux, "IMUX %p transmitting:\n", imux );
612 DBGCP_HDA ( imux, 0, hdr, len );
613
614 /* Transmit message */
615 if ( ( rc = usb_stream ( &imux->usbnet.out, iobuf, 1 ) ) != 0 )
616 goto err;
617
618 /* Increment sequence number */
619 imux->out_seq++;
620
621 return 0;
622
623 err:
624 free_iob ( iobuf );
625 return rc;
626}
627
628/**
629 * Transmit version message
630 *
631 * @v imux USB multiplexer
632 * @ret rc Return status code
633 */
634static int imux_tx_version ( struct imux *imux ) {
635 struct io_buffer *iobuf;
636 struct imux_header_version *vers;
637 int rc;
638
639 /* Allocate I/O buffer */
640 iobuf = alloc_iob ( sizeof ( *vers ) );
641 if ( ! iobuf )
642 return -ENOMEM;
643 vers = iob_put ( iobuf, sizeof ( *vers ) );
644
645 /* Construct version message */
646 memset ( vers, 0, sizeof ( *vers ) );
647 vers->hdr.protocol = htonl ( IMUX_VERSION );
648
649 /* Transmit message */
650 if ( ( rc = imux_tx ( imux, iob_disown ( iobuf ) ) ) != 0 )
651 return rc;
652
653 return 0;
654}
655
656/**
657 * Transmit pseudo-TCP message
658 *
659 * @v imux USB multiplexer
660 * @v iobuf I/O buffer
661 * @ret rc Return status code
662 */
663static int imux_tx_tcp ( struct imux *imux, struct io_buffer *iobuf ) {
664 struct imux_header_tcp *tcp = iobuf->data;
665 size_t len = iob_len ( iobuf );
666 int rc;
667
668 /* Populate TCP header */
669 assert ( len >= sizeof ( *tcp ) );
670 tcp->hdr.protocol = htonl ( IMUX_TCP );
671 tcp->tcp.src = htons ( imux->port );
673 tcp->tcp.seq = htonl ( imux->tcp_seq );
674 tcp->tcp.ack = htonl ( imux->tcp_ack );
675 tcp->tcp.hlen = ( ( sizeof ( tcp->tcp ) / 4 ) << 4 );
676 tcp->tcp.win = htons ( IMUX_WINDOW );
677
678 /* Transmit message */
679 if ( ( rc = imux_tx ( imux, iob_disown ( iobuf ) ) ) != 0 )
680 return rc;
681
682 /* Update TCP sequence */
683 imux->tcp_seq += ( len - sizeof ( *tcp ) );
684
685 return 0;
686}
687
688/**
689 * Transmit pseudo-TCP SYN
690 *
691 * @v imux USB multiplexer
692 * @ret rc Return status code
693 */
694static int imux_tx_syn ( struct imux *imux ) {
695 struct io_buffer *iobuf;
696 struct imux_header_tcp *syn;
697 int rc;
698
699 /* Allocate I/O buffer */
700 iobuf = alloc_iob ( sizeof ( *syn ) );
701 if ( ! iobuf )
702 return -ENOMEM;
703 syn = iob_put ( iobuf, sizeof ( *syn ) );
704
705 /* Construct TCP SYN message */
706 memset ( syn, 0, sizeof ( *syn ) );
707 syn->tcp.flags = TCP_SYN;
708
709 /* Transmit message */
710 if ( ( rc = imux_tx_tcp ( imux, iob_disown ( iobuf ) ) ) != 0 )
711 return rc;
712
713 /* Increment TCP sequence to compensate for SYN */
714 imux->tcp_seq++;
715
716 return 0;
717}
718
719/**
720 * Open pairing client
721 *
722 * @v imux USB multiplexer
723 * @ret rc Return status code
724 */
725static int imux_start_pair ( struct imux *imux ) {
726 int rc;
727
728 /* Disconnect any existing pairing client */
729 intf_restart ( &imux->tcp, -EPIPE );
730
731 /* Create pairing client */
732 if ( ( rc = ipair_create ( &imux->tcp, imux->flags ) ) != 0 )
733 return rc;
734
735 return 0;
736}
737
738/**
739 * Receive version message
740 *
741 * @v imux USB multiplexer
742 */
743static void imux_rx_version ( struct imux *imux ) {
744
745 /* Reset output sequence */
746 imux->out_seq = 0;
747
748 /* Send TCP SYN */
750}
751
752/**
753 * Receive log message
754 *
755 * @v imux USB multiplexer
756 * @v hdr Message header
757 * @v len Length of message
758 */
759static void imux_rx_log ( struct imux *imux, struct imux_header *hdr,
760 size_t len ) {
761 struct imux_header_log *log =
762 container_of ( hdr, struct imux_header_log, hdr );
763 unsigned int level;
764 size_t msg_len;
765 char *tmp;
766
767 /* Sanity check */
768 if ( len < sizeof ( *log ) ) {
769 DBGC ( imux, "IMUX %p malformed log message:\n", imux );
770 DBGC_HDA ( imux, 0, log, len );
771 return;
772 }
773
774 /* First byte is the log level, followed by a printable
775 * message with no NUL terminator. Extract the log level,
776 * then shuffle the message down within the buffer and append
777 * a NUL terminator.
778 */
779 msg_len = ( len - sizeof ( *log ) );
780 level = log->level;
781 tmp = ( ( void * ) &log->level );
782 memmove ( tmp, &log->msg, msg_len );
783 tmp[msg_len] = '\0';
784
785 /* Print log message */
786 DBGC ( imux, "IMUX %p <%d>: %s\n", imux, level, tmp );
787}
788
789/**
790 * Receive pseudo-TCP SYN+ACK
791 *
792 * @v imux USB multiplexer
793 */
794static void imux_rx_syn ( struct imux *imux ) {
795
796 /* Increment TCP acknowledgement to compensate for SYN */
797 imux->tcp_ack++;
798
799 /* Start pairing client */
801}
802
803/**
804 * Receive pseudo-TCP message
805 *
806 * @v imux USB multiplexer
807 * @v iobuf I/O buffer
808 */
809static void imux_rx_tcp ( struct imux *imux, struct io_buffer *iobuf ) {
810 struct imux_header_tcp *tcp;
811 size_t len = iob_len ( iobuf );
812 int rc;
813
814 /* Sanity check */
815 if ( len < sizeof ( *tcp ) ) {
816 DBGC ( imux, "IMUX %p malformed TCP message:\n", imux );
817 DBGC_HDA ( imux, 0, iobuf->data, len );
818 goto error;
819 }
820 tcp = iobuf->data;
821
822 /* Ignore unexpected packets */
823 if ( tcp->tcp.dest != htons ( imux->port ) ) {
824 DBGC ( imux, "IMUX %p ignoring unexpected TCP port %d:\n",
825 imux, ntohs ( tcp->tcp.dest ) );
826 DBGC_HDA ( imux, 0, tcp, len );
827 goto error;
828 }
829
830 /* Ignore resets */
831 if ( tcp->tcp.flags & TCP_RST ) {
832 DBGC ( imux, "IMUX %p ignoring TCP RST\n", imux );
833 DBGC2_HDA ( imux, 0, tcp, len );
834 goto error;
835 }
836
837 /* Record ACK number */
838 imux->tcp_ack = ( ntohl ( tcp->tcp.seq ) + len - sizeof ( *tcp ) );
839
840 /* Handle received message */
841 if ( tcp->tcp.flags & TCP_SYN ) {
842
843 /* Received SYN+ACK */
844 imux_rx_syn ( imux );
845
846 } else {
847
848 /* Strip header */
849 iob_pull ( iobuf, sizeof ( *tcp ) );
850
851 /* Deliver via socket */
852 if ( ( rc = xfer_deliver_iob ( &imux->tcp,
853 iob_disown ( iobuf ) ) ) != 0 )
854 goto error;
855 }
856
857 error:
858 free_iob ( iobuf );
859}
860
861/**
862 * Complete bulk IN transfer
863 *
864 * @v ep USB endpoint
865 * @v iobuf I/O buffer
866 * @v rc Completion status code
867 */
868static void imux_in_complete ( struct usb_endpoint *ep,
869 struct io_buffer *iobuf, int rc ) {
870 struct imux *imux = container_of ( ep, struct imux, usbnet.in );
871 struct imux_header *hdr;
872 size_t len = iob_len ( iobuf );
873
874 /* Ignore packets cancelled when the endpoint closes */
875 if ( ! ep->open )
876 goto drop;
877
878 /* Report USB errors */
879 if ( rc != 0 ) {
880 DBGC ( imux, "IMUX %p bulk IN failed: %s\n",
881 imux, strerror ( rc ) );
882 goto drop;
883 }
884
885 /* Sanity check */
886 if ( len < sizeof ( *hdr ) ) {
887 DBGC ( imux, "IMUX %p malformed message:\n", imux );
888 DBGC_HDA ( imux, 0, iobuf->data, len );
889 goto drop;
890 }
891 hdr = iobuf->data;
892
893 /* Record input sequence */
894 imux->in_seq = ntohs ( hdr->in_seq );
895
896 /* Handle according to protocol */
897 DBGCP ( imux, "IMUX %p received:\n", imux );
898 DBGCP_HDA ( imux, 0, hdr, len );
899 switch ( hdr->protocol ) {
900 case htonl ( IMUX_VERSION ):
902 break;
903 case htonl ( IMUX_LOG ):
904 imux_rx_log ( imux, hdr, len );
905 break;
906 case htonl ( IMUX_TCP ):
907 imux_rx_tcp ( imux, iob_disown ( iobuf ) );
908 break;
909 default:
910 DBGC ( imux, "IMUX %p unknown message type %d:\n",
911 imux, ntohl ( hdr->protocol ) );
912 DBGC_HDA ( imux, 0, hdr, len );
913 break;
914 }
915
916 drop:
917 free_iob ( iobuf );
918}
919
920/** Bulk IN endpoint operations */
924
925/**
926 * Complete bulk OUT transfer
927 *
928 * @v ep USB endpoint
929 * @v iobuf I/O buffer
930 * @v rc Completion status code
931 */
932static void imux_out_complete ( struct usb_endpoint *ep,
933 struct io_buffer *iobuf, int rc ) {
934 struct imux *imux = container_of ( ep, struct imux, usbnet.out );
935
936 /* Report USB errors */
937 if ( rc != 0 ) {
938 DBGC ( imux, "IMUX %p bulk OUT failed: %s\n",
939 imux, strerror ( rc ) );
940 goto error;
941 }
942
943 error:
944 free_iob ( iobuf );
945}
946
947/** Bulk OUT endpoint operations */
951
952/**
953 * Shut down USB multiplexer
954 *
955 * @v imux USB multiplexer
956 */
957static void imux_shutdown ( struct imux *imux ) {
958
959 /* Shut down interfaces */
961
962 /* Close USB network device, if open */
963 if ( process_running ( &imux->process ) ) {
966 }
967}
968
969/**
970 * Close USB multiplexer
971 *
972 * @v imux USB multiplexer
973 * @v rc Reason for close
974 */
975static void imux_close ( struct imux *imux, int rc ) {
976 struct iphone *iphone;
977
978 /* Restart interfaces */
979 intf_restart ( &imux->tcp, rc );
980
981 /* Record pairing status */
982 imux->rc = rc;
983
984 /* Trigger link check on any associated iPhones */
985 list_for_each_entry ( iphone, &iphones, list ) {
986 if ( iphone->usb == imux->usb )
988 }
989
990 /* Retry pairing on any error */
991 if ( rc != 0 ) {
992
993 /* Increment port number */
994 imux->port++;
995
996 /* Request pairing on any retry attempt */
998
999 /* Send new pseudo-TCP SYN */
1001
1002 DBGC ( imux, "IMUX %p retrying pairing: %s\n",
1003 imux, strerror ( rc ) );
1004 return;
1005 }
1006
1007 /* Shut down multiplexer on pairing success */
1008 imux_shutdown ( imux );
1009}
1010
1011/**
1012 * Allocate I/O buffer for pseudo-TCP socket
1013 *
1014 * @v imux USB multiplexer
1015 * @v len I/O buffer payload length
1016 * @ret iobuf I/O buffer
1017 */
1018static struct io_buffer * imux_alloc_iob ( struct imux *imux __unused,
1019 size_t len ) {
1020 struct imux_header_tcp *tcp;
1021 struct io_buffer *iobuf;
1022
1023 /* Allocate I/O buffer */
1024 iobuf = alloc_iob ( sizeof ( *tcp ) + len );
1025 if ( ! iobuf )
1026 return NULL;
1027
1028 /* Reserve space for pseudo-TCP message header */
1029 iob_reserve ( iobuf, sizeof ( *tcp ) );
1030
1031 return iobuf;
1032}
1033
1034/**
1035 * Transmit packet via pseudo-TCP socket
1036 *
1037 * @v imux USB multiplexer
1038 * @v iobuf I/O buffer
1039 * @v meta Data transfer metadata
1040 * @ret rc Return status code
1041 */
1042static int imux_deliver ( struct imux *imux, struct io_buffer *iobuf,
1043 struct xfer_metadata *meta __unused ) {
1044 struct imux_header_tcp *tcp;
1045
1046 /* Prepend pseudo-TCP header */
1047 tcp = iob_push ( iobuf, sizeof ( *tcp ) );
1048 memset ( tcp, 0, sizeof ( *tcp ) );
1049 tcp->tcp.flags = TCP_ACK;
1050
1051 /* Transmit pseudo-TCP packet */
1052 return imux_tx_tcp ( imux, iob_disown ( iobuf ) );
1053}
1054
1055/** Pseudo-TCP socket interface operations */
1057 INTF_OP ( xfer_deliver, struct imux *, imux_deliver ),
1059 INTF_OP ( intf_close, struct imux *, imux_close ),
1060};
1061
1062/** Pseudo-TCP socket interface descriptor */
1064 INTF_DESC ( struct imux, tcp, imux_tcp_operations );
1065
1066/**
1067 * Multiplexer process
1068 *
1069 * @v imux USB multiplexer
1070 */
1071static void imux_step ( struct imux *imux ) {
1072 int rc;
1073
1074 /* Poll USB bus */
1075 usb_poll ( imux->bus );
1076
1077 /* Do nothing more if multiplexer has been closed */
1078 if ( ! process_running ( &imux->process ) )
1079 return;
1080
1081 /* Refill endpoints */
1082 if ( ( rc = usbnet_refill ( &imux->usbnet ) ) != 0 ) {
1083 /* Wait for next poll */
1084 return;
1085 }
1086
1087 /* Perform pending action, if any */
1088 if ( imux->action ) {
1089 if ( ( rc = imux->action ( imux ) ) != 0 )
1090 imux_close ( imux, rc );
1091 imux->action = NULL;
1092 }
1093}
1094
1095/** Multiplexer process descriptor */
1097 PROC_DESC ( struct imux, process, imux_step );
1098
1099/**
1100 * Probe device
1101 *
1102 * @v func USB function
1103 * @v config Configuration descriptor
1104 * @ret rc Return status code
1105 */
1106static int imux_probe ( struct usb_function *func,
1107 struct usb_configuration_descriptor *config ) {
1108 struct usb_device *usb = func->usb;
1109 struct imux *imux;
1110 int rc;
1111
1112 /* Allocate and initialise structure */
1113 imux = zalloc ( sizeof ( *imux ) );
1114 if ( ! imux ) {
1115 rc = -ENOMEM;
1116 goto err_alloc;
1117 }
1118 ref_init ( &imux->refcnt, NULL );
1119 imux->usb = usb;
1120 imux->bus = usb->port->hub->bus;
1129
1130 /* Describe USB network device */
1131 if ( ( rc = usbnet_describe ( &imux->usbnet, config ) ) != 0 ) {
1132 DBGC ( imux, "IMUX %p could not describe: %s\n",
1133 imux, strerror ( rc ) );
1134 goto err_describe;
1135 }
1136
1137 /* Open USB network device */
1138 if ( ( rc = usbnet_open ( &imux->usbnet ) ) != 0 ) {
1139 DBGC ( imux, "IMUX %p could not open: %s\n",
1140 imux, strerror ( rc ) );
1141 goto err_open;
1142 }
1143
1144 /* Start polling process */
1145 process_add ( &imux->process );
1146
1147 /* Add to list of multiplexers */
1148 list_add ( &imux->list, &imuxes );
1149
1150 usb_func_set_drvdata ( func, imux );
1151 return 0;
1152
1153 list_del ( &imux->list );
1154 imux_shutdown ( imux );
1155 err_open:
1156 err_describe:
1157 ref_put ( &imux->refcnt );
1158 err_alloc:
1159 return rc;
1160}
1161
1162/**
1163 * Remove device
1164 *
1165 * @v func USB function
1166 */
1167static void imux_remove ( struct usb_function *func ) {
1168 struct imux *imux = usb_func_get_drvdata ( func );
1169
1170 list_del ( &imux->list );
1171 imux_shutdown ( imux );
1172 ref_put ( &imux->refcnt );
1173}
1174
1175/** USB multiplexer device IDs */
1176static struct usb_device_id imux_ids[] = {
1177 USB_ID ( 0x05ac, 0xffff, "imux", "iPhone (multiplexer)", 0 ),
1178};
1179
1180/** USB multiplexer driver */
1181struct usb_driver imux_driver __usb_driver = {
1182 .ids = imux_ids,
1183 .id_count = ( sizeof ( imux_ids ) / sizeof ( imux_ids[0] ) ),
1184 .class = USB_CLASS_ID ( 0xff, 0xfe, 0x02 ),
1185 .score = USB_SCORE_NORMAL,
1186 .probe = imux_probe,
1187 .remove = imux_remove,
1188};
1189
1190/******************************************************************************
1191 *
1192 * iPhone pairing client
1193 *
1194 ******************************************************************************
1195 */
1196
1197/** Common prefix for all pairing messages */
1198static const char ipair_prefix[] =
1199 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1200 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
1201 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
1202 "<plist version=\"1.0\">\n"
1203 "<dict>\n"
1204 "<key>Label</key>\n"
1205 "<string>iPXE</string>\n"
1206 "<key>Request</key>\n";
1207
1208/** Common suffix for all pairing messages */
1209static const char ipair_suffix[] =
1210 "</dict>\n"
1211 "</plist>\n";
1212
1213/** Arbitrary system BUID used for pairing */
1214static const char ipair_system_buid[] = "E4DB92D2-248A-469A-AC34-92045D07E695";
1215
1216/** Arbitrary host ID used for pairing */
1217static const char ipair_host_id[] = "93CEBC27-8457-4804-9108-F42549DF6143";
1218
1219static int ipair_tx_pubkey ( struct ipair *ipair );
1220static int ipair_rx_pubkey ( struct ipair *ipair, char *msg );
1221static int ipair_tx_pair ( struct ipair *ipair );
1222static int ipair_rx_pair ( struct ipair *ipair, char *msg );
1223static int ipair_tx_session ( struct ipair *ipair );
1224static int ipair_rx_session ( struct ipair *ipair, char *msg );
1225
1226/**
1227 * Free pairing client
1228 *
1229 * @v refcnt Reference counter
1230 */
1231static void ipair_free ( struct refcnt *refcnt ) {
1232 struct ipair *ipair = container_of ( refcnt, struct ipair, refcnt );
1233
1234 icert_free ( &ipair->icert );
1235 free ( ipair );
1236}
1237
1238/**
1239 * Shut down pairing client
1240 *
1241 * @v ipair Pairing client
1242 * @v rc Reason for close
1243 */
1244static void ipair_close ( struct ipair *ipair, int rc ) {
1245
1246 /* Shut down interfaces */
1247 intf_shutdown ( &ipair->xfer, rc );
1248
1249 /* Stop timer */
1250 stop_timer ( &ipair->timer );
1251}
1252
1253/**
1254 * Transmit XML message
1255 *
1256 * @v ipair Pairing client
1257 * @v fmt Format string
1258 * @v ... Arguments
1259 * @ret rc Return status code
1260 */
1261static int __attribute__ (( format ( printf, 2, 3 ) ))
1262ipair_tx ( struct ipair *ipair, const char *fmt, ... ) {
1263 struct io_buffer *iobuf;
1264 struct ipair_header *hdr;
1265 va_list args;
1266 size_t len;
1267 char *msg;
1268 int rc;
1269
1270 /* Calculate length of formatted string */
1271 va_start ( args, fmt );
1272 len = ( vsnprintf ( NULL, 0, fmt, args ) + 1 /* NUL */ );
1273 va_end ( args );
1274
1275 /* Allocate I/O buffer */
1276 iobuf = xfer_alloc_iob ( &ipair->xfer, ( sizeof ( *hdr ) + len ) );
1277 if ( ! iobuf )
1278 return -ENOMEM;
1279 hdr = iob_put ( iobuf, sizeof ( *hdr ) );
1280
1281 /* Construct XML message */
1282 memset ( hdr, 0, sizeof ( *hdr ) );
1283 hdr->len = htonl ( len );
1284 msg = iob_put ( iobuf, len );
1285 va_start ( args, fmt );
1286 vsnprintf ( msg, len, fmt, args );
1287 va_end ( args );
1288 DBGC2 ( ipair, "IPAIR %p transmitting:\n%s\n", ipair, msg );
1289
1290 /* Transmit message */
1291 if ( ( rc = xfer_deliver_iob ( &ipair->xfer,
1292 iob_disown ( iobuf ) ) ) != 0 )
1293 return rc;
1294
1295 return 0;
1296}
1297
1298/**
1299 * Receive XML message payload
1300 *
1301 * @v ipair Pairing client
1302 * @v msg Message payload
1303 * @v len Length of message
1304 * @ret rc Return status code
1305 */
1306static int ipair_rx ( struct ipair *ipair, char *msg, size_t len ) {
1307 int ( * rx ) ( struct ipair *ipair, char *msg );
1308 int rc;
1309
1310 /* Ignore empty messages */
1311 if ( ! len )
1312 return 0;
1313
1314 /* Sanity check */
1315 if ( ( msg[ len - 1 ] != '\0' ) && ( msg[ len - 1 ] != '\n' ) ) {
1316 DBGC ( ipair, "IPAIR %p malformed XML:\n", ipair );
1317 DBGC_HDA ( ipair, 0, msg, len );
1318 return -EPROTO;
1319 }
1320
1321 /* Add NUL terminator (potentially overwriting final newline) */
1322 msg[ len - 1 ] = '\0';
1323 DBGC2 ( ipair, "IPAIR %p received:\n%s\n\n", ipair, msg );
1324
1325 /* Handle according to current state */
1326 rx = ipair->rx;
1327 if ( ! rx ) {
1328 DBGC ( ipair, "IPAIR %p unexpected XML:\n%s\n", ipair, msg );
1329 return -EPROTO;
1330 }
1331 ipair->rx = NULL;
1332 if ( ( rc = rx ( ipair, msg ) ) != 0 )
1333 return rc;
1334
1335 return 0;
1336}
1337
1338/**
1339 * Locate XML tag
1340 *
1341 * @v ipair Pairing client
1342 * @v msg XML message
1343 * @v tag Tag name
1344 * @ret start Start of tag content
1345 * @ret end End of tag content
1346 * @ret rc Return status code
1347 */
1348static int ipair_tag ( struct ipair *ipair, const char *msg, const char *tag,
1349 char **start, char **end ) {
1350 char buf[ 2 /* "</" */ + strlen ( tag ) + 1 /* ">" */ + 1 /* NUL */ ];
1351
1352 /* Locate opening tag */
1353 sprintf ( buf, "<%s>", tag );
1354 *start = strstr ( msg, buf );
1355 if ( ! *start )
1356 return -ENOENT;
1357 *start += strlen ( buf );
1358
1359 /* Locate closing tag */
1360 sprintf ( buf, "</%s>", tag );
1361 *end = strstr ( *start, buf );
1362 if ( ! *end ) {
1363 DBGC ( ipair, "IPAIR %p missing closing tag %s in:\n%s\n",
1364 ipair, buf, msg );
1365 return -ENOENT;
1366 }
1367
1368 return 0;
1369}
1370
1371/**
1372 * Locate XML property list dictionary value
1373 *
1374 * @v ipair Pairing client
1375 * @v msg XML message
1376 * @v key Key name
1377 * @v type Key type
1378 * @ret start Start of value content
1379 * @ret end End of value content
1380 * @ret rc Return status code
1381 */
1382static int ipair_key ( struct ipair *ipair, const char *msg, const char *key,
1383 const char *type, char **start, char **end ) {
1384 int rc;
1385
1386 /* Iterate over keys */
1387 while ( 1 ) {
1388
1389 /* Locate key */
1390 if ( ( rc = ipair_tag ( ipair, msg, "key", start,
1391 end ) ) != 0 )
1392 return rc;
1393 msg = *end;
1394
1395 /* Check key name */
1396 if ( memcmp ( *start, key, ( *end - *start ) ) != 0 )
1397 continue;
1398
1399 /* Locate value */
1400 return ipair_tag ( ipair, msg, type, start, end );
1401 }
1402}
1403
1404/**
1405 * Transmit DevicePublicKey message
1406 *
1407 * @v ipair Pairing client
1408 * @ret rc Return status code
1409 */
1410static int ipair_tx_pubkey ( struct ipair *ipair ) {
1411 int rc;
1412
1413 /* Transmit message */
1414 if ( ( rc = ipair_tx ( ipair,
1415 "%s"
1416 "<string>GetValue</string>\n"
1417 "<key>Key</key>\n"
1418 "<string>DevicePublicKey</string>\n"
1419 "%s",
1420 ipair_prefix, ipair_suffix ) ) != 0 )
1421 return rc;
1422
1423 return 0;
1424}
1425
1426/**
1427 * Receive DevicePublicKey message
1428 *
1429 * @v ipair Pairing client
1430 * @v msg XML message
1431 * @ret rc Return status code
1432 */
1433static int ipair_rx_pubkey ( struct ipair *ipair, char *msg ) {
1434 struct asn1_cursor *key;
1435 char *data;
1436 char *end;
1437 char *decoded;
1438 size_t max_len;
1439 int len;
1440 int next;
1441 int rc;
1442
1443 /* Locate "Value" value */
1444 if ( ( rc = ipair_key ( ipair, msg, "Value", "data", &data,
1445 &end ) ) != 0 ) {
1446 DBGC ( ipair, "IPAIR %p unexpected public key message:\n%s\n",
1447 ipair, msg );
1448 goto err_tag;
1449 }
1450 *end = '\0';
1451
1452 /* Decode outer layer of Base64 */
1453 max_len = base64_decoded_max_len ( data );
1454 decoded = malloc ( max_len );
1455 if ( ! decoded ) {
1456 rc = -ENOMEM;
1457 goto err_alloc;
1458 }
1459 len = base64_decode ( data, decoded, max_len );
1460 if ( len < 0 ) {
1461 rc = len;
1462 DBGC ( ipair, "IPAIR %p invalid outer public key:\n%s\n",
1463 ipair, data );
1464 goto err_decode;
1465 }
1466
1467 /* Decode inner layer of Base64 */
1468 next = pem_asn1 ( decoded, len, 0, &key );
1469 if ( next < 0 ) {
1470 rc = next;
1471 DBGC ( ipair, "IPAIR %p invalid inner public key:\n%s\n",
1472 ipair, decoded );
1473 goto err_asn1;
1474 }
1475 DBGC ( ipair, "IPAIR %p received public key\n", ipair );
1476 DBGC2_HDA ( ipair, 0, key->data, key->len );
1477
1478 /* Construct certificates */
1479 if ( ( rc = icert_certs ( &ipair->icert, key ) ) != 0 )
1480 goto err_certs;
1481
1482 /* Send session request or pair request as applicable */
1483 if ( ipair->flags & IPAIR_REQUEST ) {
1486 } else {
1489 }
1491
1492 /* Free key */
1493 free ( key );
1494
1495 /* Free intermediate Base64 */
1496 free ( decoded );
1497
1498 return 0;
1499
1500 err_certs:
1501 free ( key );
1502 err_asn1:
1503 err_decode:
1504 free ( decoded );
1505 err_alloc:
1506 err_tag:
1507 return rc;
1508}
1509
1510/**
1511 * Transmit Pair message
1512 *
1513 * @v ipair Pairing client
1514 * @ret rc Return status code
1515 */
1516static int ipair_tx_pair ( struct ipair *ipair ) {
1517 char *root;
1518 char *host;
1519 char *device;
1520 int rc;
1521
1522 /* Construct doubly encoded certificates */
1523 if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.root,
1524 &root ) ) != 0 )
1525 goto err_root;
1526 if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.host,
1527 &host ) ) != 0 )
1528 goto err_host;
1529 if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.device,
1530 &device ) ) != 0 )
1531 goto err_device;
1532
1533 /* Transmit message */
1534 if ( ( rc = ipair_tx ( ipair,
1535 "%s"
1536 "<string>Pair</string>\n"
1537 "<key>PairRecord</key>\n"
1538 "<dict>\n"
1539 "<key>RootCertificate</key>\n"
1540 "<data>%s</data>\n"
1541 "<key>HostCertificate</key>\n"
1542 "<data>%s</data>\n"
1543 "<key>DeviceCertificate</key>\n"
1544 "<data>%s</data>\n"
1545 "<key>SystemBUID</key>\n"
1546 "<string>%s</string>\n"
1547 "<key>HostID</key>\n"
1548 "<string>%s</string>\n"
1549 "</dict>\n"
1550 "<key>ProtocolVersion</key>\n"
1551 "<string>2</string>\n"
1552 "<key>PairingOptions</key>\n"
1553 "<dict>\n"
1554 "<key>ExtendedPairingErrors</key>\n"
1555 "<true/>\n"
1556 "</dict>\n"
1557 "%s",
1558 ipair_prefix, root, host, device,
1561 ) ) != 0 )
1562 goto err_tx;
1563
1564 err_tx:
1565 free ( device );
1566 err_device:
1567 free ( host );
1568 err_host:
1569 free ( root );
1570 err_root:
1571 return rc;
1572}
1573
1574/**
1575 * Receive Pair message error
1576 *
1577 * @v ipair Pairing client
1578 * @v error Pairing error
1579 * @ret rc Return status code
1580 */
1581static int ipair_rx_pair_error ( struct ipair *ipair, char *error ) {
1582
1583 /* Check for actual errors */
1584 if ( strcmp ( error, "PairingDialogResponsePending" ) != 0 ) {
1585 DBGC ( ipair, "IPAIR %p pairing error \"%s\"\n", ipair, error );
1586 return -EPERM;
1587 }
1588
1589 /* Retransmit pairing request */
1593
1594 DBGC ( ipair, "IPAIR %p waiting for pairing dialog\n", ipair );
1595 return 0;
1596}
1597
1598/**
1599 * Receive Pair message
1600 *
1601 * @v ipair Pairing client
1602 * @v msg XML message
1603 * @ret rc Return status code
1604 */
1605static int ipair_rx_pair ( struct ipair *ipair, char *msg ) {
1606 char *error;
1607 char *escrow;
1608 char *end;
1609 int rc;
1610
1611 /* Check for pairing errors */
1612 if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1613 &end ) ) == 0 ) {
1614 *end = '\0';
1615 return ipair_rx_pair_error ( ipair, error );
1616 }
1617
1618 /* Get EscrowBag */
1619 if ( ( rc = ipair_key ( ipair, msg, "EscrowBag", "data", &escrow,
1620 &end ) ) != 0 ) {
1621 DBGC ( ipair, "IPAIR %p unexpected pairing response:\n%s\n",
1622 ipair, msg );
1623 return rc;
1624 }
1625 DBGC ( ipair, "IPAIR %p pairing successful\n", ipair );
1626
1627 /* Send session request */
1631
1632 return 0;
1633}
1634
1635/**
1636 * Transmit StartSession message
1637 *
1638 * @v ipair Pairing client
1639 * @ret rc Return status code
1640 */
1641static int ipair_tx_session ( struct ipair *ipair ) {
1642 int rc;
1643
1644 /* Transmit message */
1645 if ( ( rc = ipair_tx ( ipair,
1646 "%s"
1647 "<string>StartSession</string>\n"
1648 "<key>SystemBUID</key>\n"
1649 "<string>%s</string>\n"
1650 "<key>HostID</key>\n"
1651 "<string>%s</string>\n"
1652 "%s",
1655 ) ) != 0 )
1656 return rc;
1657
1658 return 0;
1659}
1660
1661/**
1662 * Receive StartSession message error
1663 *
1664 * @v ipair Pairing client
1665 * @v error Pairing error
1666 * @ret rc Return status code
1667 */
1668static int ipair_rx_session_error ( struct ipair *ipair, char *error ) {
1669
1670 /* Check for actual errors */
1671 if ( strcmp ( error, "InvalidHostID" ) != 0 ) {
1672 DBGC ( ipair, "IPAIR %p session error \"%s\"\n", ipair, error );
1673 return -EPERM;
1674 }
1675
1676 /* Transmit pairing request */
1680
1681 DBGC ( ipair, "IPAIR %p unknown host: requesting pairing\n", ipair );
1682 return 0;
1683}
1684
1685/**
1686 * Receive StartSession message
1687 *
1688 * @v ipair Pairing client
1689 * @v msg XML message
1690 * @ret rc Return status code
1691 */
1692static int ipair_rx_session ( struct ipair *ipair, char *msg ) {
1693 char *error;
1694 char *session;
1695 char *end;
1696 int rc;
1697
1698 /* Check for session errors */
1699 if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1700 &end ) ) == 0 ) {
1701 *end = '\0';
1703 }
1704
1705 /* Check for session ID */
1706 if ( ( rc = ipair_key ( ipair, msg, "SessionID", "string", &session,
1707 &end ) ) != 0 ) {
1708 DBGC ( ipair, "IPAIR %p unexpected session response:\n%s\n",
1709 ipair, msg );
1710 return rc;
1711 }
1712 *end = '\0';
1713 DBGC ( ipair, "IPAIR %p starting session \"%s\"\n", ipair, session );
1714
1715 /* Start TLS */
1716 if ( ( rc = add_tls ( &ipair->xfer, "iPhone", &icert_root,
1717 ipair->icert.key ) ) != 0 ) {
1718 DBGC ( ipair, "IPAIR %p could not start TLS: %s\n",
1719 ipair, strerror ( rc ) );
1720 return rc;
1721 }
1722
1723 /* Record that TLS has been started */
1724 ipair->flags |= IPAIR_TLS;
1725
1726 return 0;
1727}
1728
1729/**
1730 * Handle window change notification
1731 *
1732 * @v ipair Pairing client
1733 */
1734static void ipair_window_changed ( struct ipair *ipair ) {
1735
1736 /* Report pairing as complete once TLS session has been established */
1737 if ( ( ipair->flags & IPAIR_TLS ) && xfer_window ( &ipair->xfer ) ) {
1738
1739 /* Sanity checks */
1745
1746 /* Report pairing as complete */
1747 DBGC ( ipair, "IPAIR %p established TLS session\n", ipair );
1748 ipair_close ( ipair, 0 );
1749 return;
1750 }
1751}
1752
1753/**
1754 * Handle received data
1755 *
1756 * @v ipair Pairing client
1757 * @v iobuf I/O buffer
1758 * @v meta Data transfer metadata
1759 * @ret rc Return status code
1760 */
1761static int ipair_deliver ( struct ipair *ipair, struct io_buffer *iobuf,
1762 struct xfer_metadata *meta __unused ) {
1763 struct ipair_header *hdr;
1764 int rc;
1765
1766 /* Strip header (which may appear in a separate packet) */
1767 if ( ( ! ( ipair->flags & IPAIR_RX_LEN ) ) &&
1768 ( iob_len ( iobuf ) >= sizeof ( *hdr ) ) ) {
1769 iob_pull ( iobuf, sizeof ( *hdr ) );
1771 }
1772
1773 /* Clear received header flag if we have a message */
1774 if ( iob_len ( iobuf ) )
1776
1777 /* Receive message */
1778 if ( ( rc = ipair_rx ( ipair, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
1779 goto error;
1780
1781 /* Free I/O buffer */
1782 free_iob ( iobuf );
1783
1784 return 0;
1785
1786 error:
1787 ipair_close ( ipair, rc );
1788 free_iob ( iobuf );
1789 return rc;
1790}
1791
1792/**
1793 * Pairing transmission timer
1794 *
1795 * @v timer Retransmission timer
1796 * @v over Failure indicator
1797 */
1798static void ipair_expired ( struct retry_timer *timer, int over __unused ) {
1799 struct ipair *ipair = container_of ( timer, struct ipair, timer );
1800 int ( * tx ) ( struct ipair *ipair );
1801 int rc;
1802
1803 /* Sanity check */
1804 tx = ipair->tx;
1805 assert ( tx != NULL );
1806
1807 /* Clear pending transmission */
1808 ipair->tx = NULL;
1809
1810 /* Transmit data, if applicable */
1811 if ( ( rc = tx ( ipair ) ) != 0 )
1812 ipair_close ( ipair, rc );
1813}
1814
1815/** Pairing client interface operations */
1821
1822/** Pairing client interface descriptor */
1824 INTF_DESC ( struct ipair, xfer, ipair_xfer_operations );
1825
1826/**
1827 * Create a pairing client
1828 *
1829 * @v xfer Data transfer interface
1830 * @v flags Initial state flags
1831 * @ret rc Return status code
1832 */
1833static int ipair_create ( struct interface *xfer, unsigned int flags ) {
1834 struct ipair *ipair;
1835 int rc;
1836
1837 /* Allocate and initialise structure */
1838 ipair = zalloc ( sizeof ( *ipair ) );
1839 if ( ! ipair ) {
1840 rc = -ENOMEM;
1841 goto err_alloc;
1842 }
1845 timer_init ( &ipair->timer, ipair_expired, &ipair->refcnt );
1848 ipair->flags = flags;
1849
1850 /* Schedule initial transmission */
1852
1853 /* Attach to parent interface, mortalise self, and return */
1855 ref_put ( &ipair->refcnt );
1856 return 0;
1857
1858 ref_put ( &ipair->refcnt );
1859 err_alloc:
1860 return rc;
1861}
1862
1863/******************************************************************************
1864 *
1865 * iPhone USB networking
1866 *
1867 ******************************************************************************
1868 */
1869
1870/**
1871 * Complete bulk IN transfer
1872 *
1873 * @v ep USB endpoint
1874 * @v iobuf I/O buffer
1875 * @v rc Completion status code
1876 */
1877static void iphone_in_complete ( struct usb_endpoint *ep,
1878 struct io_buffer *iobuf, int rc ) {
1879 struct iphone *iphone = container_of ( ep, struct iphone, usbnet.in );
1880 struct net_device *netdev = iphone->netdev;
1881
1882 /* Profile receive completions */
1883 profile_start ( &iphone_in_profiler );
1884
1885 /* Ignore packets cancelled when the endpoint closes */
1886 if ( ! ep->open )
1887 goto ignore;
1888
1889 /* Record USB errors against the network device */
1890 if ( rc != 0 ) {
1891 DBGC ( iphone, "IPHONE %p bulk IN failed: %s\n",
1892 iphone, strerror ( rc ) );
1893 goto error;
1894 }
1895
1896 /* Strip padding */
1897 if ( iob_len ( iobuf ) < IPHONE_IN_PAD ) {
1898 DBGC ( iphone, "IPHONE %p malformed bulk IN:\n", iphone );
1899 DBGC_HDA ( iphone, 0, iobuf->data, iob_len ( iobuf ) );
1900 rc = -EINVAL;
1901 goto error;
1902 }
1903 iob_pull ( iobuf, IPHONE_IN_PAD );
1904
1905 /* Hand off to network stack */
1906 netdev_rx ( netdev, iob_disown ( iobuf ) );
1907
1908 profile_stop ( &iphone_in_profiler );
1909 return;
1910
1911 error:
1912 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
1913 ignore:
1914 free_iob ( iobuf );
1915}
1916
1917/** Bulk IN endpoint operations */
1921
1922/**
1923 * Transmit packet
1924 *
1925 * @v iphone iPhone device
1926 * @v iobuf I/O buffer
1927 * @ret rc Return status code
1928 */
1929static int iphone_out_transmit ( struct iphone *iphone,
1930 struct io_buffer *iobuf ) {
1931 int rc;
1932
1933 /* Profile transmissions */
1934 profile_start ( &iphone_out_profiler );
1935
1936 /* Enqueue I/O buffer */
1937 if ( ( rc = usb_stream ( &iphone->usbnet.out, iobuf, 1 ) ) != 0 )
1938 return rc;
1939
1940 profile_stop ( &iphone_out_profiler );
1941 return 0;
1942}
1943
1944/**
1945 * Complete bulk OUT transfer
1946 *
1947 * @v ep USB endpoint
1948 * @v iobuf I/O buffer
1949 * @v rc Completion status code
1950 */
1951static void iphone_out_complete ( struct usb_endpoint *ep,
1952 struct io_buffer *iobuf, int rc ) {
1953 struct iphone *iphone = container_of ( ep, struct iphone, usbnet.out );
1954 struct net_device *netdev = iphone->netdev;
1955
1956 /* Report TX completion */
1957 netdev_tx_complete_err ( netdev, iobuf, rc );
1958}
1959
1960/** Bulk OUT endpoint operations */
1964
1965/**
1966 * Check pairing status
1967 *
1968 * @v iphone iPhone device
1969 * @ret rc Return status code
1970 */
1971static int iphone_check_pair ( struct iphone *iphone ) {
1972 struct imux *imux;
1973
1974 /* Find corresponding USB multiplexer */
1975 list_for_each_entry ( imux, &imuxes, list ) {
1976 if ( imux->usb == iphone->usb )
1977 return imux->rc;
1978 }
1979
1980 return -EPIPE_NO_MUX;
1981}
1982
1983/**
1984 * Check link status
1985 *
1986 * @v netdev Network device
1987 */
1988static void iphone_check_link ( struct net_device *netdev ) {
1989 struct iphone *iphone = netdev->priv;
1990 struct usb_device *usb = iphone->usb;
1992 int rc;
1993
1994 /* Check pairing status */
1995 if ( ( rc = iphone_check_pair ( iphone ) ) != 0 )
1996 goto err_pair;
1997
1998 /* Get link status */
1999 if ( ( rc = usb_control ( usb, IPHONE_GET_LINK, 0, 0, &status,
2000 sizeof ( status ) ) ) != 0 ) {
2001 DBGC ( iphone, "IPHONE %p could not get link status: %s\n",
2002 iphone, strerror ( rc ) );
2003 goto err_control;
2004 }
2005
2006 /* Check link status */
2007 if ( status != IPHONE_LINK_UP ) {
2008 rc = -ENOTCONN_STATUS ( status );
2009 goto err_status;
2010 }
2011
2012 /* Success */
2013 rc = 0;
2014
2015 err_status:
2016 err_control:
2017 err_pair:
2018 /* Report link status. Since we have to check the link
2019 * periodically (due to an absence of an interrupt endpoint),
2020 * do this only if the link status has actually changed.
2021 */
2022 if ( rc != netdev->link_rc ) {
2023 if ( rc == 0 ) {
2024 DBGC ( iphone, "IPHONE %p link up\n", iphone );
2025 } else {
2026 DBGC ( iphone, "IPHONE %p link down: %s\n",
2027 iphone, strerror ( rc ) );
2028 }
2030 }
2031}
2032
2033/**
2034 * Periodically update link status
2035 *
2036 * @v timer Link status timer
2037 * @v over Failure indicator
2038 */
2039static void iphone_expired ( struct retry_timer *timer, int over __unused ) {
2040 struct iphone *iphone = container_of ( timer, struct iphone, timer );
2041 struct net_device *netdev = iphone->netdev;
2042
2043 /* Check link status */
2045
2046 /* Restart timer, if device is open */
2047 if ( netdev_is_open ( netdev ) )
2049}
2050
2051/**
2052 * Open network device
2053 *
2054 * @v netdev Network device
2055 * @ret rc Return status code
2056 */
2057static int iphone_open ( struct net_device *netdev ) {
2058 struct iphone *iphone = netdev->priv;
2059 int rc;
2060
2061 /* Open USB network device */
2062 if ( ( rc = usbnet_open ( &iphone->usbnet ) ) != 0 ) {
2063 DBGC ( iphone, "IPHONE %p could not open: %s\n",
2064 iphone, strerror ( rc ) );
2065 goto err_open;
2066 }
2067
2068 /* Start the link status check timer */
2070
2071 return 0;
2072
2074 err_open:
2075 return rc;
2076}
2077
2078/**
2079 * Close network device
2080 *
2081 * @v netdev Network device
2082 */
2083static void iphone_close ( struct net_device *netdev ) {
2084 struct iphone *iphone = netdev->priv;
2085
2086 /* Stop the link status check timer */
2087 stop_timer ( &iphone->timer );
2088
2089 /* Close USB network device */
2091}
2092
2093/**
2094 * Transmit packet
2095 *
2096 * @v netdev Network device
2097 * @v iobuf I/O buffer
2098 * @ret rc Return status code
2099 */
2100static int iphone_transmit ( struct net_device *netdev,
2101 struct io_buffer *iobuf ) {
2102 struct iphone *iphone = netdev->priv;
2103 int rc;
2104
2105 /* Transmit packet */
2106 if ( ( rc = iphone_out_transmit ( iphone, iobuf ) ) != 0 )
2107 return rc;
2108
2109 return 0;
2110}
2111
2112/**
2113 * Poll for completed and received packets
2114 *
2115 * @v netdev Network device
2116 */
2117static void iphone_poll ( struct net_device *netdev ) {
2118 struct iphone *iphone = netdev->priv;
2119 int rc;
2120
2121 /* Poll USB bus */
2122 usb_poll ( iphone->bus );
2123
2124 /* Refill endpoints */
2125 if ( ( rc = usbnet_refill ( &iphone->usbnet ) ) != 0 )
2127}
2128
2129/** iPhone network device operations */
2131 .open = iphone_open,
2132 .close = iphone_close,
2133 .transmit = iphone_transmit,
2134 .poll = iphone_poll,
2135};
2136
2137/**
2138 * Probe device
2139 *
2140 * @v func USB function
2141 * @v config Configuration descriptor
2142 * @ret rc Return status code
2143 */
2144static int iphone_probe ( struct usb_function *func,
2145 struct usb_configuration_descriptor *config ) {
2146 struct usb_device *usb = func->usb;
2147 struct net_device *netdev;
2148 struct iphone *iphone;
2149 int rc;
2150
2151 /* Allocate and initialise structure */
2152 netdev = alloc_etherdev ( sizeof ( *iphone ) );
2153 if ( ! netdev ) {
2154 rc = -ENOMEM;
2155 goto err_alloc;
2156 }
2158 netdev->dev = &func->dev;
2159 iphone = netdev->priv;
2160 memset ( iphone, 0, sizeof ( *iphone ) );
2161 iphone->usb = usb;
2162 iphone->bus = usb->port->hub->bus;
2163 iphone->netdev = netdev;
2168 timer_init ( &iphone->timer, iphone_expired, &netdev->refcnt );
2169 DBGC ( iphone, "IPHONE %p on %s\n", iphone, func->name );
2170
2171 /* Describe USB network device */
2172 if ( ( rc = usbnet_describe ( &iphone->usbnet, config ) ) != 0 ) {
2173 DBGC ( iphone, "IPHONE %p could not describe: %s\n",
2174 iphone, strerror ( rc ) );
2175 goto err_describe;
2176 }
2177
2178 /* Fetch MAC address */
2179 if ( ( rc = usb_control ( usb, IPHONE_GET_MAC, 0, 0, netdev->hw_addr,
2180 ETH_ALEN ) ) != 0 ) {
2181 DBGC ( iphone, "IPHONE %p could not fetch MAC address: %s\n",
2182 iphone, strerror ( rc ) );
2183 goto err_fetch_mac;
2184 }
2185
2186 /* Register network device */
2187 if ( ( rc = register_netdev ( netdev ) ) != 0 )
2188 goto err_register;
2189
2190 /* Set initial link status */
2192
2193 /* Add to list of iPhone network devices */
2194 list_add ( &iphone->list, &iphones );
2195
2196 usb_func_set_drvdata ( func, iphone );
2197 return 0;
2198
2199 list_del ( &iphone->list );
2201 err_register:
2202 err_fetch_mac:
2203 err_describe:
2205 netdev_put ( netdev );
2206 err_alloc:
2207 return rc;
2208}
2209
2210/**
2211 * Remove device
2212 *
2213 * @v func USB function
2214 */
2215static void iphone_remove ( struct usb_function *func ) {
2216 struct iphone *iphone = usb_func_get_drvdata ( func );
2217 struct net_device *netdev = iphone->netdev;
2218
2219 list_del ( &iphone->list );
2222 netdev_put ( netdev );
2223}
2224
2225/** iPhone device IDs */
2226static struct usb_device_id iphone_ids[] = {
2227 USB_ROM ( 0x05ac, 0xffff, "iphone", "iPhone", 0 ),
2228};
2229
2230/** iPhone driver */
2231struct usb_driver iphone_driver __usb_driver = {
2232 .ids = iphone_ids,
2233 .id_count = ( sizeof ( iphone_ids ) / sizeof ( iphone_ids[0] ) ),
2234 .class = USB_CLASS_ID ( 0xff, 0xfd, 0x01 ),
2235 .score = USB_SCORE_NORMAL,
2236 .probe = iphone_probe,
2237 .remove = iphone_remove,
2238};
2239
2240/* Drag in objects via iphone_driver */
2241REQUIRING_SYMBOL ( iphone_driver );
2242
2243/* Drag in RSA-with-SHA256 OID prefixes */
2244REQUIRE_OBJECT ( rsa_sha256 );
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
__be32 raw[7]
Definition CIB_PRM.h:0
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
union @162305117151260234136356364136041353210355154177 key
#define SHA256_DIGEST_SIZE
Definition Tpm20.h:29
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
struct arbelprm_completion_with_error error
Definition arbel.h:1
unsigned char uint8_t
Definition stdint.h:10
int asn1_prepend(struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
Prepend data to ASN.1 builder.
Definition asn1.c:1042
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition asn1.c:1019
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition asn1.c:1069
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_UTF8_STRING
ASN.1 UTF-8 string.
Definition asn1.h:81
#define ASN1_BIT_STRING
ASN.1 bit string.
Definition asn1.h:66
static struct asn1_cursor * asn1_built(struct asn1_builder *builder)
Get cursor for built object.
Definition asn1.h:499
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition asn1.h:99
#define ASN1_NULL
ASN.1 null.
Definition asn1.h:72
#define ASN1_OID
ASN.1 object identifier.
Definition asn1.h:75
#define ASN1_OID_COMMON_NAME
ASN.1 OID for commonName (2.5.4.3).
Definition asn1.h:328
#define ASN1_BOOLEAN
ASN.1 boolean.
Definition asn1.h:60
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition asn1.h:408
#define ASN1_OID_BASICCONSTRAINTS
ASN.1 OID for id-ce-basicConstraints (2.5.29.19).
Definition asn1.h:338
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
#define ASN1_SHORT(tag,...)
Construct a short ASN.1 value.
Definition asn1.h:105
#define ASN1_OID_KEYUSAGE
ASN.1 OID for id-ce-keyUsage (2.5.29.15).
Definition asn1.h:333
#define ASN1_SET
ASN.1 set.
Definition asn1.h:93
#define ASN1_OID_SHA256WITHRSAENCRYPTION
ASN.1 OID for sha256WithRSAEncryption (1.2.840.113549.1.1.11).
Definition asn1.h:192
#define ASN1_GENERALIZED_TIME
ASN.1 generalized time.
Definition asn1.h:87
#define ASN1_OID_RSAENCRYPTION
ASN.1 OID for rsaEncryption (1.2.840.113549.1.1.1).
Definition asn1.h:168
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
size_t base64_encode(const void *raw, size_t raw_len, char *data, size_t len)
Base64-encode data.
Definition base64.c:52
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition base64.c:92
Base64 encoding.
static size_t base64_decoded_max_len(const char *encoded)
Calculate maximum length of base64-decoded string.
Definition base64.h:35
static size_t base64_encoded_len(size_t raw_len)
Calculate length of base64-encoded data.
Definition base64.h:22
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
uint64_t tag
Identity tag.
Definition edd.h:1
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t flags
Flags.
Definition ena.h:7
uint8_t status
Status.
Definition ena.h:5
uint8_t meta
Metadata flags.
Definition ena.h:3
Error codes.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:266
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:598
#define DBGCP_HDA(...)
Definition compiler.h:565
#define DBGC2(...)
Definition compiler.h:547
#define DBGCP(...)
Definition compiler.h:564
#define DBGC2_HDA(...)
Definition compiler.h:548
#define DBGC(...)
Definition compiler.h:530
#define DBGC_HDA(...)
Definition compiler.h:531
uint32_t start
Starting offset.
Definition netvsc.h:1
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:227
#define ENOENT
No such file or directory.
Definition errno.h:558
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EPROTO
Protocol error.
Definition errno.h:668
#define EPIPE
Broken pipe.
Definition errno.h:663
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ECANCELED
Operation canceled.
Definition errno.h:387
#define EPERM
Operation not permitted.
Definition errno.h:658
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
Definition compiler.h:140
#define ETH_ALEN
Definition if_ether.h:9
#define ntohl(value)
Definition byteswap.h:135
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
#define __attribute__(x)
Definition compiler.h:10
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:294
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:305
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:299
static int pubkey_sign(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Definition crypto.h:376
Profiling.
#define __profiler
Declare a profiler.
Definition profile.h:61
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
Universal Serial Bus (USB).
#define __usb_driver
Declare a USB driver.
Definition usb.h:1463
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition usb.h:627
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1411
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1082
#define USB_ROM(_vendor, _product, _name, _description, _data)
Definition usb.h:1391
#define USB_ID(_vendor, _product, _name, _description, _data)
Definition usb.h:1383
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:717
@ USB_SCORE_NORMAL
Normal driver.
Definition usb.h:1475
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:728
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
void * memmove(void *dest, const void *src, size_t len) __nonnull
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_push(iobuf, len)
Definition iobuf.h:149
#define iob_put(iobuf, len)
Definition iobuf.h:185
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_reserve(iobuf, len)
Definition iobuf.h:132
#define iob_pull(iobuf, len)
Definition iobuf.h:167
static struct usb_device_id iphone_ids[]
iPhone device IDs
Definition iphone.c:2226
static struct interface_operation ipair_xfer_operations[]
Pairing client interface operations.
Definition iphone.c:1816
static void imux_shutdown(struct imux *imux)
Shut down USB multiplexer.
Definition iphone.c:957
static int imux_start_pair(struct imux *imux)
Open pairing client.
Definition iphone.c:725
#define icert_public
Definition iphone.c:317
static struct io_buffer * imux_alloc_iob(struct imux *imux __unused, size_t len)
Allocate I/O buffer for pseudo-TCP socket.
Definition iphone.c:1018
static int ipair_tx_pair(struct ipair *ipair)
Transmit Pair message.
Definition iphone.c:1516
static int ipair_create(struct interface *xfer, unsigned int flags)
Create a pairing client.
Definition iphone.c:1833
static int ipair_tag(struct ipair *ipair, const char *msg, const char *tag, char **start, char **end)
Locate XML tag.
Definition iphone.c:1348
static const char ipair_suffix[]
Common suffix for all pairing messages.
Definition iphone.c:1209
static int ipair_rx_session_error(struct ipair *ipair, char *error)
Receive StartSession message error.
Definition iphone.c:1668
static int ipair_rx_pair_error(struct ipair *ipair, char *error)
Receive Pair message error.
Definition iphone.c:1581
static int ipair_tx_pubkey(struct ipair *ipair)
Transmit DevicePublicKey message.
Definition iphone.c:1410
static int ipair_key(struct ipair *ipair, const char *msg, const char *key, const char *type, char **start, char **end)
Locate XML property list dictionary value.
Definition iphone.c:1382
static const uint8_t icert_name_iphone_data[]
"iPhone" subject name
Definition iphone.c:225
static const uint8_t icert_name_root_data[]
"Root" subject name
Definition iphone.c:201
static int icert_cert(struct icert *icert, struct asn1_cursor *subject, struct asn1_cursor *issuer, struct asn1_cursor *private, struct asn1_cursor *public, struct asn1_cursor *exts, struct x509_certificate **cert)
Construct certificate.
Definition iphone.c:355
static struct asn1_cursor icert_leaf_exts
Extensions used in constructed leaf certificates.
Definition iphone.c:171
static void iphone_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition iphone.c:2117
static void imux_rx_version(struct imux *imux)
Receive version message.
Definition iphone.c:743
static int ipair_rx_pair(struct ipair *ipair, char *msg)
Receive Pair message.
Definition iphone.c:1605
static int icert_encode(struct icert *icert, struct x509_certificate *cert, char **encenc)
Construct doubly base64-encoded certificate.
Definition iphone.c:531
static int iphone_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition iphone.c:2144
static const uint8_t icert_sha256_rsa[]
"SHA-256 with RSA algorithm" identifier used in constructed certificates
Definition iphone.c:114
static void ipair_close(struct ipair *ipair, int rc)
Shut down pairing client.
Definition iphone.c:1244
static struct usb_endpoint_driver_operations imux_out_operations
Bulk OUT endpoint operations.
Definition iphone.c:948
static const uint8_t icert_name_ipxe_data[]
"iPXE" subject name
Definition iphone.c:213
static uint8_t icert_root_fingerprint[SHA256_DIGEST_SIZE]
iPhone root certificate fingerprint
Definition iphone.c:92
static void imux_remove(struct usb_function *func)
Remove device.
Definition iphone.c:1167
static const char icert_end[]
PEM certificate suffix.
Definition iphone.c:324
static void imux_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition iphone.c:932
static const uint8_t icert_validity[]
Validity period in constructed certificates.
Definition iphone.c:187
static void imux_rx_log(struct imux *imux, struct imux_header *hdr, size_t len)
Receive log message.
Definition iphone.c:759
#define EPIPE_NO_MUX
Definition iphone.c:52
static int imux_tx_version(struct imux *imux)
Transmit version message.
Definition iphone.c:634
static struct interface_operation imux_tcp_operations[]
Pseudo-TCP socket interface operations.
Definition iphone.c:1056
static int iphone_open(struct net_device *netdev)
Open network device.
Definition iphone.c:2057
static int ipair_tx(struct ipair *ipair, const char *fmt,...)
Transmit XML message.
Definition iphone.c:1262
static struct asn1_cursor icert_name_iphone
"iPhone" subject name
Definition iphone.c:234
static struct usb_endpoint_driver_operations imux_in_operations
Bulk IN endpoint operations.
Definition iphone.c:921
static int iphone_out_transmit(struct iphone *iphone, struct io_buffer *iobuf)
Transmit packet.
Definition iphone.c:1929
static const char ipair_host_id[]
Arbitrary host ID used for pairing.
Definition iphone.c:1217
static const uint8_t icert_tbs_prefix[]
"TBSCertificate" prefix in constructed certificates
Definition iphone.c:175
static void ipair_free(struct refcnt *refcnt)
Free pairing client.
Definition iphone.c:1231
static int ipair_tx_session(struct ipair *ipair)
Transmit StartSession message.
Definition iphone.c:1641
static struct usb_endpoint_driver_operations iphone_out_operations
Bulk OUT endpoint operations.
Definition iphone.c:1961
static void iphone_remove(struct usb_function *func)
Remove device.
Definition iphone.c:2215
static const uint8_t icert_leaf_exts_data[]
Extensions used in constructed leaf certificates.
Definition iphone.c:142
static const char icert_begin[]
PEM certificate prefix.
Definition iphone.c:321
static void iphone_expired(struct retry_timer *timer, int over __unused)
Periodically update link status.
Definition iphone.c:2039
static struct asn1_cursor icert_name_root
"Root" subject name
Definition iphone.c:209
static const char ipair_prefix[]
Common prefix for all pairing messages.
Definition iphone.c:1198
static void imux_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition iphone.c:868
#define icert_private
Definition iphone.c:318
#define EINPROGRESS_PAIRING
Definition iphone.c:56
static int ipair_rx(struct ipair *ipair, char *msg, size_t len)
Receive XML message payload.
Definition iphone.c:1306
static int ipair_rx_session(struct ipair *ipair, char *msg)
Receive StartSession message.
Definition iphone.c:1692
static void icert_free(struct icert *icert)
Free pairing certificates.
Definition iphone.c:331
static const char ipair_system_buid[]
Arbitrary system BUID used for pairing.
Definition iphone.c:1214
static void iphone_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition iphone.c:1877
static struct interface_descriptor ipair_xfer_desc
Pairing client interface descriptor.
Definition iphone.c:1823
static int imux_tx_syn(struct imux *imux)
Transmit pseudo-TCP SYN.
Definition iphone.c:694
static int ipair_rx_pubkey(struct ipair *ipair, char *msg)
Receive DevicePublicKey message.
Definition iphone.c:1433
static void iphone_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition iphone.c:1951
static int icert_certs(struct icert *icert, struct asn1_cursor *key)
Construct certificates.
Definition iphone.c:448
static struct interface_descriptor imux_tcp_desc
Pseudo-TCP socket interface descriptor.
Definition iphone.c:1063
static int ipair_deliver(struct ipair *ipair, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle received data.
Definition iphone.c:1761
static const uint8_t icert_rsa[]
"RSA algorithm" identifier used in constructed certificates
Definition iphone.c:106
static struct x509_root icert_root
Root of trust for iPhone certificates.
Definition iphone.c:95
static const uint8_t icert_nul[]
Single zero byte used in constructed certificates.
Definition iphone.c:103
static int iphone_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition iphone.c:2100
static void imux_step(struct imux *imux)
Multiplexer process.
Definition iphone.c:1071
static void iphone_close(struct net_device *netdev)
Close network device.
Definition iphone.c:2083
static int imux_deliver(struct imux *imux, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Transmit packet via pseudo-TCP socket.
Definition iphone.c:1042
static int imux_tx(struct imux *imux, struct io_buffer *iobuf)
Transmit message.
Definition iphone.c:601
static void ipair_window_changed(struct ipair *ipair)
Handle window change notification.
Definition iphone.c:1734
static void imux_close(struct imux *imux, int rc)
Close USB multiplexer.
Definition iphone.c:975
static struct asn1_cursor icert_root_exts
Extensions used in constructed root certificate.
Definition iphone.c:138
static void imux_rx_syn(struct imux *imux)
Receive pseudo-TCP SYN+ACK.
Definition iphone.c:794
static int imux_tx_tcp(struct imux *imux, struct io_buffer *iobuf)
Transmit pseudo-TCP message.
Definition iphone.c:663
static struct net_device_operations iphone_operations
iPhone network device operations
Definition iphone.c:2130
#define ENOTCONN_STATUS(status)
Definition iphone.c:64
static struct usb_endpoint_driver_operations iphone_in_operations
Bulk IN endpoint operations.
Definition iphone.c:1918
static int imux_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition iphone.c:1106
static struct usb_device_id imux_ids[]
USB multiplexer device IDs.
Definition iphone.c:1176
static struct process_descriptor imux_process_desc
Multiplexer process descriptor.
Definition iphone.c:1096
static void iphone_check_link(struct net_device *netdev)
Check link status.
Definition iphone.c:1988
static int iphone_check_pair(struct iphone *iphone)
Check pairing status.
Definition iphone.c:1971
static const uint8_t icert_root_exts_data[]
Extensions used in constructed root certificate.
Definition iphone.c:121
static void ipair_expired(struct retry_timer *timer, int over __unused)
Pairing transmission timer.
Definition iphone.c:1798
static struct asn1_cursor icert_name_ipxe
"iPXE" subject name
Definition iphone.c:221
static void imux_rx_tcp(struct imux *imux, struct io_buffer *iobuf)
Receive pseudo-TCP message.
Definition iphone.c:809
iPhone USB Ethernet driver
#define IMUX_IN_MAX_FILL
Multiplexer bulk IN maximum fill level.
Definition iphone.h:159
#define IMUX_PORT_LOCAL
Local port number.
Definition iphone.h:103
#define IMUX_IN_MTU
Multiplexer bulk IN buffer size.
Definition iphone.h:165
#define IPHONE_IN_MTU
Bulk IN buffer size.
Definition iphone.h:278
#define IPHONE_IN_PAD
Bulk IN padding.
Definition iphone.h:272
#define IPHONE_LINK_CHECK_INTERVAL
Link check interval.
Definition iphone.h:290
#define IMUX_WINDOW
Advertised TCP window.
Definition iphone.h:112
@ IPAIR_TLS
TLS session has been started.
Definition iphone.h:218
@ IPAIR_RX_LEN
Standalone length has been received.
Definition iphone.h:216
@ IPAIR_REQUEST
Request a new pairing.
Definition iphone.h:214
#define IMUX_PORT_LOCKDOWND
Lockdown daemon port number.
Definition iphone.h:106
#define IPHONE_GET_MAC
Get MAC address.
Definition iphone.h:235
#define IPHONE_GET_LINK
Get link status.
Definition iphone.h:240
#define IPAIR_RETRY_DELAY
Pairing retry delay.
Definition iphone.h:225
@ IPHONE_LINK_UP
Link up.
Definition iphone.h:249
#define IPHONE_IN_MAX_FILL
Bulk IN maximum fill level.
Definition iphone.h:284
@ IMUX_LOG
Log message.
Definition iphone.h:68
@ IMUX_TCP
TCP packet.
Definition iphone.h:70
@ IMUX_VERSION
Version number.
Definition iphone.h:66
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition message.c:62
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition netdevice.c:208
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:946
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
Network device management.
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:665
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:522
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:535
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
uint32_t end
Ending offset.
Definition netvsc.h:7
int pem_asn1(const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from PEM data.
Definition pem.c:104
PEM-encoded ASN.1 data.
static void privkey_init(struct private_key *key)
Initialise empty private key.
Definition privkey.h:64
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition privkey.h:42
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
static void process_init(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process and add to process list.
Definition process.h:162
static int process_running(struct process *process)
Check if process is running.
Definition process.h:176
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition process.h:83
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition refcnt.c:102
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition refcnt.h:78
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition retry.h:100
struct pubkey_algorithm rsa_algorithm
RSA public-key algorithm.
Definition rsa.c:833
RSA public-key cryptography.
SHA-256 algorithm.
#define SHA256_CTX_SIZE
SHA-256 context size.
Definition sha256.h:55
struct digest_algorithm sha256_algorithm
#define va_end(ap)
Definition stdarg.h:10
#define va_start(ap, last)
Definition stdarg.h:8
__builtin_va_list va_list
Definition stdarg.h:7
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition stdio.h:37
struct stp_switch root
Root switch.
Definition stp.h:15
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
char * strstr(const char *haystack, const char *needle)
Find substring.
Definition string.c:324
char * strcpy(char *dest, const char *src)
Copy string.
Definition string.c:378
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An ASN.1 object builder.
Definition asn1.h:29
void * data
Data.
Definition asn1.h:36
size_t len
Length of data.
Definition asn1.h:38
An ASN.1 object cursor.
Definition asn1.h:21
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
A hardware device.
Definition device.h:77
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
An iPhone pairing certificate set.
Definition iphone.h:31
struct x509_certificate * device
Device certificate.
Definition iphone.h:39
struct private_key * key
"Private" key
Definition iphone.h:33
struct x509_certificate * host
Host certificate.
Definition iphone.h:37
struct x509_certificate * root
Root certificate.
Definition iphone.h:35
An iPhone USB multiplexed log message header.
Definition iphone.h:82
uint8_t level
Log level.
Definition iphone.h:86
char msg[0]
Message.
Definition iphone.h:88
An iPhone USB multiplexed pseudo-TCP message header.
Definition iphone.h:92
struct tcp_header tcp
Pseudo-TCP header.
Definition iphone.h:96
An iPhone USB multiplexed version message header.
Definition iphone.h:74
struct imux_header hdr
Multiplexed packet header.
Definition iphone.h:76
An iPhone USB multiplexed packet header.
Definition iphone.h:50
uint32_t protocol
Protocol.
Definition iphone.h:52
An iPhone USB multiplexer.
Definition iphone.h:115
struct process process
Polling process.
Definition iphone.h:128
uint16_t in_seq
Input sequence.
Definition iphone.h:137
uint16_t out_seq
Output sequence.
Definition iphone.h:139
struct usbnet_device usbnet
USB network device.
Definition iphone.h:123
uint16_t port
Pseudo-TCP local port number.
Definition iphone.h:145
int(* action)(struct imux *imux)
Pending action.
Definition iphone.h:134
struct refcnt refcnt
Reference counter.
Definition iphone.h:117
struct usb_bus * bus
USB bus.
Definition iphone.h:121
int rc
Pairing status.
Definition iphone.h:152
struct usb_device * usb
USB device.
Definition iphone.h:119
struct list_head list
List of USB multiplexers.
Definition iphone.h:125
uint32_t tcp_ack
Pseudo-TCP acknowledgement number.
Definition iphone.h:143
struct interface tcp
Pseudo-TCP lockdown socket interface.
Definition iphone.h:148
uint32_t tcp_seq
Pseudo-TCP sequence number.
Definition iphone.h:141
unsigned int flags
Pairing flags.
Definition iphone.h:150
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:98
void * data
Start of data.
Definition iobuf.h:113
An iPhone USB multiplexed pseudo-TCP XML message header.
Definition iphone.h:175
An iPhone pairing client.
Definition iphone.h:183
struct interface xfer
Data transfer interface.
Definition iphone.h:187
struct retry_timer timer
Pairing timer.
Definition iphone.h:190
unsigned int flags
State flags.
Definition iphone.h:205
int(* tx)(struct ipair *ipair)
Transmit message.
Definition iphone.h:196
struct refcnt refcnt
Reference counter.
Definition iphone.h:185
int(* rx)(struct ipair *ipair, char *msg)
Receive message.
Definition iphone.h:203
struct icert icert
Pairing certificates.
Definition iphone.h:208
An iPhone network device.
Definition iphone.h:255
struct usb_device * usb
USB device.
Definition iphone.h:257
struct net_device * netdev
Network device.
Definition iphone.h:261
struct list_head list
List of iPhone network devices.
Definition iphone.h:266
struct retry_timer timer
Link status check timer.
Definition iphone.h:268
struct usb_bus * bus
USB bus.
Definition iphone.h:259
struct usbnet_device usbnet
USB network device.
Definition iphone.h:263
Network device operations.
Definition netdevice.h:214
A network device.
Definition netdevice.h:353
struct asn1_builder builder
ASN.1 object builder.
Definition privkey.h:21
A process descriptor.
Definition process.h:32
A process.
Definition process.h:18
A data structure for storing profiling information.
Definition profile.h:27
A public key algorithm.
Definition crypto.h:142
A reference counter.
Definition refcnt.h:27
A retry timer.
Definition retry.h:22
uint8_t hlen
Definition tcp.h:25
uint8_t flags
Definition tcp.h:26
uint32_t seq
Definition tcp.h:23
uint16_t win
Definition tcp.h:27
uint16_t src
Definition tcp.h:21
uint16_t dest
Definition tcp.h:22
uint32_t ack
Definition tcp.h:24
A timer.
Definition timer.h:29
A USB configuration descriptor.
Definition usb.h:210
A USB device ID.
Definition usb.h:1371
A USB device.
Definition usb.h:733
struct usb_port * port
USB port.
Definition usb.h:737
A USB driver.
Definition usb.h:1429
USB endpoint driver operations.
Definition usb.h:499
A USB endpoint.
Definition usb.h:414
int open
Endpoint is open.
Definition usb.h:429
A USB function.
Definition usb.h:684
struct usb_device * usb
USB device.
Definition usb.h:688
struct device dev
Generic device.
Definition usb.h:692
const char * name
Name.
Definition usb.h:686
struct usb_bus * bus
USB bus.
Definition usb.h:855
struct usb_hub * hub
USB hub.
Definition usb.h:825
struct usb_endpoint out
Bulk OUT endpoint.
Definition usbnet.h:32
struct usb_endpoint in
Bulk IN endpoint.
Definition usbnet.h:30
An X.509 certificate.
Definition x509.h:216
struct asn1_cursor raw
Raw certificate.
Definition x509.h:231
An X.509 root certificate list.
Definition x509.h:375
Data transfer metadata.
Definition xfer.h:23
#define TCP_ACK
Definition tcp.h:160
#define TCP_RST
Definition tcp.h:162
#define TCP_SYN
Definition tcp.h:163
int add_tls(struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
Add TLS on an interface.
Definition tls.c:4389
Transport Layer Security Protocol.
int usb_control(struct usb_device *usb, unsigned int request, unsigned int value, unsigned int index, void *data, size_t len)
Issue USB control transaction.
Definition usb.c:783
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition usb.c:545
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition usbnet.c:152
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition usbnet.c:55
void usbnet_close(struct usbnet_device *usbnet)
Close USB network device.
Definition usbnet.c:128
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition usbnet.c:278
static void usbnet_init(struct usbnet_device *usbnet, struct usb_function *func, struct usb_endpoint_driver_operations *intr, struct usb_endpoint_driver_operations *in, struct usb_endpoint_driver_operations *out)
Initialise USB network device.
Definition usbnet.h:45
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:485
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
Write a formatted string to a buffer.
Definition vsprintf.c:352
int ssize_t const char * fmt
Definition vsprintf.h:73
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition wpa.h:4
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition x509.c:1313
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition x509.c:147
void x509_fingerprint(struct x509_certificate *cert, struct digest_algorithm *digest, void *fingerprint)
Calculate X.509 certificate fingerprint.
Definition x509.c:1237
X.509 certificates.
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition x509.h:278
@ X509_DIGITAL_SIGNATURE
Definition x509.h:102
@ X509_KEY_ENCIPHERMENT
Definition x509.h:104
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256
Data transfer interfaces.
int const char * format
Definition xfer.h:105