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 ( *hdr ) );
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 = iobuf->data;
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, tcp, len );
818 goto error;
819 }
820
821 /* Ignore unexpected packets */
822 if ( tcp->tcp.dest != htons ( imux->port ) ) {
823 DBGC ( imux, "IMUX %p ignoring unexpected TCP port %d:\n",
824 imux, ntohs ( tcp->tcp.dest ) );
825 DBGC_HDA ( imux, 0, tcp, len );
826 goto error;
827 }
828
829 /* Ignore resets */
830 if ( tcp->tcp.flags & TCP_RST ) {
831 DBGC ( imux, "IMUX %p ignoring TCP RST\n", imux );
832 DBGC2_HDA ( imux, 0, tcp, len );
833 goto error;
834 }
835
836 /* Record ACK number */
837 imux->tcp_ack = ( ntohl ( tcp->tcp.seq ) + len - sizeof ( *tcp ) );
838
839 /* Handle received message */
840 if ( tcp->tcp.flags & TCP_SYN ) {
841
842 /* Received SYN+ACK */
843 imux_rx_syn ( imux );
844
845 } else {
846
847 /* Strip header */
848 iob_pull ( iobuf, sizeof ( *tcp ) );
849
850 /* Deliver via socket */
851 if ( ( rc = xfer_deliver_iob ( &imux->tcp,
852 iob_disown ( iobuf ) ) ) != 0 )
853 goto error;
854 }
855
856 error:
857 free_iob ( iobuf );
858}
859
860/**
861 * Complete bulk IN transfer
862 *
863 * @v ep USB endpoint
864 * @v iobuf I/O buffer
865 * @v rc Completion status code
866 */
867static void imux_in_complete ( struct usb_endpoint *ep,
868 struct io_buffer *iobuf, int rc ) {
869 struct imux *imux = container_of ( ep, struct imux, usbnet.in );
870 struct imux_header *hdr = iobuf->data;
871 size_t len = iob_len ( iobuf );
872
873 /* Ignore packets cancelled when the endpoint closes */
874 if ( ! ep->open )
875 goto drop;
876
877 /* Report USB errors */
878 if ( rc != 0 ) {
879 DBGC ( imux, "IMUX %p bulk IN failed: %s\n",
880 imux, strerror ( rc ) );
881 goto drop;
882 }
883
884 /* Sanity check */
885 if ( len < sizeof ( *hdr ) ) {
886 DBGC ( imux, "IMUX %p malformed message:\n", imux );
887 DBGC_HDA ( imux, 0, hdr, len );
888 goto drop;
889 }
890
891 /* Record input sequence */
892 imux->in_seq = ntohs ( hdr->in_seq );
893
894 /* Handle according to protocol */
895 DBGCP ( imux, "IMUX %p received:\n", imux );
896 DBGCP_HDA ( imux, 0, hdr, len );
897 switch ( hdr->protocol ) {
898 case htonl ( IMUX_VERSION ):
900 break;
901 case htonl ( IMUX_LOG ):
902 imux_rx_log ( imux, hdr, len );
903 break;
904 case htonl ( IMUX_TCP ):
905 imux_rx_tcp ( imux, iob_disown ( iobuf ) );
906 break;
907 default:
908 DBGC ( imux, "IMUX %p unknown message type %d:\n",
909 imux, ntohl ( hdr->protocol ) );
910 DBGC_HDA ( imux, 0, hdr, len );
911 break;
912 }
913
914 drop:
915 free_iob ( iobuf );
916}
917
918/** Bulk IN endpoint operations */
922
923/**
924 * Complete bulk OUT transfer
925 *
926 * @v ep USB endpoint
927 * @v iobuf I/O buffer
928 * @v rc Completion status code
929 */
930static void imux_out_complete ( struct usb_endpoint *ep,
931 struct io_buffer *iobuf, int rc ) {
932 struct imux *imux = container_of ( ep, struct imux, usbnet.out );
933
934 /* Report USB errors */
935 if ( rc != 0 ) {
936 DBGC ( imux, "IMUX %p bulk OUT failed: %s\n",
937 imux, strerror ( rc ) );
938 goto error;
939 }
940
941 error:
942 free_iob ( iobuf );
943}
944
945/** Bulk OUT endpoint operations */
949
950/**
951 * Shut down USB multiplexer
952 *
953 * @v imux USB multiplexer
954 */
955static void imux_shutdown ( struct imux *imux ) {
956
957 /* Shut down interfaces */
959
960 /* Close USB network device, if open */
961 if ( process_running ( &imux->process ) ) {
964 }
965}
966
967/**
968 * Close USB multiplexer
969 *
970 * @v imux USB multiplexer
971 * @v rc Reason for close
972 */
973static void imux_close ( struct imux *imux, int rc ) {
974 struct iphone *iphone;
975
976 /* Restart interfaces */
977 intf_restart ( &imux->tcp, rc );
978
979 /* Record pairing status */
980 imux->rc = rc;
981
982 /* Trigger link check on any associated iPhones */
983 list_for_each_entry ( iphone, &iphones, list ) {
984 if ( iphone->usb == imux->usb )
986 }
987
988 /* Retry pairing on any error */
989 if ( rc != 0 ) {
990
991 /* Increment port number */
992 imux->port++;
993
994 /* Request pairing on any retry attempt */
996
997 /* Send new pseudo-TCP SYN */
999
1000 DBGC ( imux, "IMUX %p retrying pairing: %s\n",
1001 imux, strerror ( rc ) );
1002 return;
1003 }
1004
1005 /* Shut down multiplexer on pairing success */
1006 imux_shutdown ( imux );
1007}
1008
1009/**
1010 * Allocate I/O buffer for pseudo-TCP socket
1011 *
1012 * @v imux USB multiplexer
1013 * @v len I/O buffer payload length
1014 * @ret iobuf I/O buffer
1015 */
1016static struct io_buffer * imux_alloc_iob ( struct imux *imux __unused,
1017 size_t len ) {
1018 struct imux_header_tcp *tcp;
1019 struct io_buffer *iobuf;
1020
1021 /* Allocate I/O buffer */
1022 iobuf = alloc_iob ( sizeof ( *tcp ) + len );
1023 if ( ! iobuf )
1024 return NULL;
1025
1026 /* Reserve space for pseudo-TCP message header */
1027 iob_reserve ( iobuf, sizeof ( *tcp ) );
1028
1029 return iobuf;
1030}
1031
1032/**
1033 * Transmit packet via pseudo-TCP socket
1034 *
1035 * @v imux USB multiplexer
1036 * @v iobuf I/O buffer
1037 * @v meta Data transfer metadata
1038 * @ret rc Return status code
1039 */
1040static int imux_deliver ( struct imux *imux, struct io_buffer *iobuf,
1041 struct xfer_metadata *meta __unused ) {
1042 struct imux_header_tcp *tcp;
1043
1044 /* Prepend pseudo-TCP header */
1045 tcp = iob_push ( iobuf, sizeof ( *tcp ) );
1046 memset ( tcp, 0, sizeof ( *tcp ) );
1047 tcp->tcp.flags = TCP_ACK;
1048
1049 /* Transmit pseudo-TCP packet */
1050 return imux_tx_tcp ( imux, iob_disown ( iobuf ) );
1051}
1052
1053/** Pseudo-TCP socket interface operations */
1055 INTF_OP ( xfer_deliver, struct imux *, imux_deliver ),
1057 INTF_OP ( intf_close, struct imux *, imux_close ),
1058};
1059
1060/** Pseudo-TCP socket interface descriptor */
1062 INTF_DESC ( struct imux, tcp, imux_tcp_operations );
1063
1064/**
1065 * Multiplexer process
1066 *
1067 * @v imux USB multiplexer
1068 */
1069static void imux_step ( struct imux *imux ) {
1070 int rc;
1071
1072 /* Poll USB bus */
1073 usb_poll ( imux->bus );
1074
1075 /* Do nothing more if multiplexer has been closed */
1076 if ( ! process_running ( &imux->process ) )
1077 return;
1078
1079 /* Refill endpoints */
1080 if ( ( rc = usbnet_refill ( &imux->usbnet ) ) != 0 ) {
1081 /* Wait for next poll */
1082 return;
1083 }
1084
1085 /* Perform pending action, if any */
1086 if ( imux->action ) {
1087 if ( ( rc = imux->action ( imux ) ) != 0 )
1088 imux_close ( imux, rc );
1089 imux->action = NULL;
1090 }
1091}
1092
1093/** Multiplexer process descriptor */
1095 PROC_DESC ( struct imux, process, imux_step );
1096
1097/**
1098 * Probe device
1099 *
1100 * @v func USB function
1101 * @v config Configuration descriptor
1102 * @ret rc Return status code
1103 */
1104static int imux_probe ( struct usb_function *func,
1105 struct usb_configuration_descriptor *config ) {
1106 struct usb_device *usb = func->usb;
1107 struct imux *imux;
1108 int rc;
1109
1110 /* Allocate and initialise structure */
1111 imux = zalloc ( sizeof ( *imux ) );
1112 if ( ! imux ) {
1113 rc = -ENOMEM;
1114 goto err_alloc;
1115 }
1116 ref_init ( &imux->refcnt, NULL );
1117 imux->usb = usb;
1118 imux->bus = usb->port->hub->bus;
1127
1128 /* Describe USB network device */
1129 if ( ( rc = usbnet_describe ( &imux->usbnet, config ) ) != 0 ) {
1130 DBGC ( imux, "IMUX %p could not describe: %s\n",
1131 imux, strerror ( rc ) );
1132 goto err_describe;
1133 }
1134
1135 /* Open USB network device */
1136 if ( ( rc = usbnet_open ( &imux->usbnet ) ) != 0 ) {
1137 DBGC ( imux, "IMUX %p could not open: %s\n",
1138 imux, strerror ( rc ) );
1139 goto err_open;
1140 }
1141
1142 /* Start polling process */
1143 process_add ( &imux->process );
1144
1145 /* Add to list of multiplexers */
1146 list_add ( &imux->list, &imuxes );
1147
1148 usb_func_set_drvdata ( func, imux );
1149 return 0;
1150
1151 list_del ( &imux->list );
1152 imux_shutdown ( imux );
1153 err_open:
1154 err_describe:
1155 ref_put ( &imux->refcnt );
1156 err_alloc:
1157 return rc;
1158}
1159
1160/**
1161 * Remove device
1162 *
1163 * @v func USB function
1164 */
1165static void imux_remove ( struct usb_function *func ) {
1166 struct imux *imux = usb_func_get_drvdata ( func );
1167
1168 list_del ( &imux->list );
1169 imux_shutdown ( imux );
1170 ref_put ( &imux->refcnt );
1171}
1172
1173/** USB multiplexer device IDs */
1174static struct usb_device_id imux_ids[] = {
1175 USB_ID ( 0x05ac, 0xffff, "imux", "iPhone (multiplexer)", 0 ),
1176};
1177
1178/** USB multiplexer driver */
1179struct usb_driver imux_driver __usb_driver = {
1180 .ids = imux_ids,
1181 .id_count = ( sizeof ( imux_ids ) / sizeof ( imux_ids[0] ) ),
1182 .class = USB_CLASS_ID ( 0xff, 0xfe, 0x02 ),
1183 .score = USB_SCORE_NORMAL,
1184 .probe = imux_probe,
1185 .remove = imux_remove,
1186};
1187
1188/******************************************************************************
1189 *
1190 * iPhone pairing client
1191 *
1192 ******************************************************************************
1193 */
1194
1195/** Common prefix for all pairing messages */
1196static const char ipair_prefix[] =
1197 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1198 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
1199 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
1200 "<plist version=\"1.0\">\n"
1201 "<dict>\n"
1202 "<key>Label</key>\n"
1203 "<string>iPXE</string>\n"
1204 "<key>Request</key>\n";
1205
1206/** Common suffix for all pairing messages */
1207static const char ipair_suffix[] =
1208 "</dict>\n"
1209 "</plist>\n";
1210
1211/** Arbitrary system BUID used for pairing */
1212static const char ipair_system_buid[] = "E4DB92D2-248A-469A-AC34-92045D07E695";
1213
1214/** Arbitrary host ID used for pairing */
1215static const char ipair_host_id[] = "93CEBC27-8457-4804-9108-F42549DF6143";
1216
1217static int ipair_tx_pubkey ( struct ipair *ipair );
1218static int ipair_rx_pubkey ( struct ipair *ipair, char *msg );
1219static int ipair_tx_pair ( struct ipair *ipair );
1220static int ipair_rx_pair ( struct ipair *ipair, char *msg );
1221static int ipair_tx_session ( struct ipair *ipair );
1222static int ipair_rx_session ( struct ipair *ipair, char *msg );
1223
1224/**
1225 * Free pairing client
1226 *
1227 * @v refcnt Reference counter
1228 */
1229static void ipair_free ( struct refcnt *refcnt ) {
1230 struct ipair *ipair = container_of ( refcnt, struct ipair, refcnt );
1231
1232 icert_free ( &ipair->icert );
1233 free ( ipair );
1234}
1235
1236/**
1237 * Shut down pairing client
1238 *
1239 * @v ipair Pairing client
1240 * @v rc Reason for close
1241 */
1242static void ipair_close ( struct ipair *ipair, int rc ) {
1243
1244 /* Shut down interfaces */
1245 intf_shutdown ( &ipair->xfer, rc );
1246
1247 /* Stop timer */
1248 stop_timer ( &ipair->timer );
1249}
1250
1251/**
1252 * Transmit XML message
1253 *
1254 * @v ipair Pairing client
1255 * @v fmt Format string
1256 * @v ... Arguments
1257 * @ret rc Return status code
1258 */
1259static int __attribute__ (( format ( printf, 2, 3 ) ))
1260ipair_tx ( struct ipair *ipair, const char *fmt, ... ) {
1261 struct io_buffer *iobuf;
1262 struct ipair_header *hdr;
1263 va_list args;
1264 size_t len;
1265 char *msg;
1266 int rc;
1267
1268 /* Calculate length of formatted string */
1269 va_start ( args, fmt );
1270 len = ( vsnprintf ( NULL, 0, fmt, args ) + 1 /* NUL */ );
1271 va_end ( args );
1272
1273 /* Allocate I/O buffer */
1274 iobuf = xfer_alloc_iob ( &ipair->xfer, ( sizeof ( *hdr ) + len ) );
1275 if ( ! iobuf )
1276 return -ENOMEM;
1277 hdr = iob_put ( iobuf, sizeof ( *hdr ) );
1278
1279 /* Construct XML message */
1280 memset ( hdr, 0, sizeof ( *hdr ) );
1281 hdr->len = htonl ( len );
1282 msg = iob_put ( iobuf, len );
1283 va_start ( args, fmt );
1284 vsnprintf ( msg, len, fmt, args );
1285 va_end ( args );
1286 DBGC2 ( ipair, "IPAIR %p transmitting:\n%s\n", ipair, msg );
1287
1288 /* Transmit message */
1289 if ( ( rc = xfer_deliver_iob ( &ipair->xfer,
1290 iob_disown ( iobuf ) ) ) != 0 )
1291 return rc;
1292
1293 return 0;
1294}
1295
1296/**
1297 * Receive XML message payload
1298 *
1299 * @v ipair Pairing client
1300 * @v msg Message payload
1301 * @v len Length of message
1302 * @ret rc Return status code
1303 */
1304static int ipair_rx ( struct ipair *ipair, char *msg, size_t len ) {
1305 int ( * rx ) ( struct ipair *ipair, char *msg );
1306 int rc;
1307
1308 /* Ignore empty messages */
1309 if ( ! len )
1310 return 0;
1311
1312 /* Sanity check */
1313 if ( ( msg[ len - 1 ] != '\0' ) && ( msg[ len - 1 ] != '\n' ) ) {
1314 DBGC ( ipair, "IPAIR %p malformed XML:\n", ipair );
1315 DBGC_HDA ( ipair, 0, msg, len );
1316 return -EPROTO;
1317 }
1318
1319 /* Add NUL terminator (potentially overwriting final newline) */
1320 msg[ len - 1 ] = '\0';
1321 DBGC2 ( ipair, "IPAIR %p received:\n%s\n\n", ipair, msg );
1322
1323 /* Handle according to current state */
1324 rx = ipair->rx;
1325 if ( ! rx ) {
1326 DBGC ( ipair, "IPAIR %p unexpected XML:\n%s\n", ipair, msg );
1327 return -EPROTO;
1328 }
1329 ipair->rx = NULL;
1330 if ( ( rc = rx ( ipair, msg ) ) != 0 )
1331 return rc;
1332
1333 return 0;
1334}
1335
1336/**
1337 * Locate XML tag
1338 *
1339 * @v ipair Pairing client
1340 * @v msg XML message
1341 * @v tag Tag name
1342 * @ret start Start of tag content
1343 * @ret end End of tag content
1344 * @ret rc Return status code
1345 */
1346static int ipair_tag ( struct ipair *ipair, const char *msg, const char *tag,
1347 char **start, char **end ) {
1348 char buf[ 2 /* "</" */ + strlen ( tag ) + 1 /* ">" */ + 1 /* NUL */ ];
1349
1350 /* Locate opening tag */
1351 sprintf ( buf, "<%s>", tag );
1352 *start = strstr ( msg, buf );
1353 if ( ! *start )
1354 return -ENOENT;
1355 *start += strlen ( buf );
1356
1357 /* Locate closing tag */
1358 sprintf ( buf, "</%s>", tag );
1359 *end = strstr ( *start, buf );
1360 if ( ! *end ) {
1361 DBGC ( ipair, "IPAIR %p missing closing tag %s in:\n%s\n",
1362 ipair, buf, msg );
1363 return -ENOENT;
1364 }
1365
1366 return 0;
1367}
1368
1369/**
1370 * Locate XML property list dictionary value
1371 *
1372 * @v ipair Pairing client
1373 * @v msg XML message
1374 * @v key Key name
1375 * @v type Key type
1376 * @ret start Start of value content
1377 * @ret end End of value content
1378 * @ret rc Return status code
1379 */
1380static int ipair_key ( struct ipair *ipair, const char *msg, const char *key,
1381 const char *type, char **start, char **end ) {
1382 int rc;
1383
1384 /* Iterate over keys */
1385 while ( 1 ) {
1386
1387 /* Locate key */
1388 if ( ( rc = ipair_tag ( ipair, msg, "key", start,
1389 end ) ) != 0 )
1390 return rc;
1391 msg = *end;
1392
1393 /* Check key name */
1394 if ( memcmp ( *start, key, ( *end - *start ) ) != 0 )
1395 continue;
1396
1397 /* Locate value */
1398 return ipair_tag ( ipair, msg, type, start, end );
1399 }
1400}
1401
1402/**
1403 * Transmit DevicePublicKey message
1404 *
1405 * @v ipair Pairing client
1406 * @ret rc Return status code
1407 */
1408static int ipair_tx_pubkey ( struct ipair *ipair ) {
1409 int rc;
1410
1411 /* Transmit message */
1412 if ( ( rc = ipair_tx ( ipair,
1413 "%s"
1414 "<string>GetValue</string>\n"
1415 "<key>Key</key>\n"
1416 "<string>DevicePublicKey</string>\n"
1417 "%s",
1418 ipair_prefix, ipair_suffix ) ) != 0 )
1419 return rc;
1420
1421 return 0;
1422}
1423
1424/**
1425 * Receive DevicePublicKey message
1426 *
1427 * @v ipair Pairing client
1428 * @v msg XML message
1429 * @ret rc Return status code
1430 */
1431static int ipair_rx_pubkey ( struct ipair *ipair, char *msg ) {
1432 struct asn1_cursor *key;
1433 char *data;
1434 char *end;
1435 char *decoded;
1436 size_t max_len;
1437 int len;
1438 int next;
1439 int rc;
1440
1441 /* Locate "Value" value */
1442 if ( ( rc = ipair_key ( ipair, msg, "Value", "data", &data,
1443 &end ) ) != 0 ) {
1444 DBGC ( ipair, "IPAIR %p unexpected public key message:\n%s\n",
1445 ipair, msg );
1446 goto err_tag;
1447 }
1448 *end = '\0';
1449
1450 /* Decode outer layer of Base64 */
1451 max_len = base64_decoded_max_len ( data );
1452 decoded = malloc ( max_len );
1453 if ( ! decoded ) {
1454 rc = -ENOMEM;
1455 goto err_alloc;
1456 }
1457 len = base64_decode ( data, decoded, max_len );
1458 if ( len < 0 ) {
1459 rc = len;
1460 DBGC ( ipair, "IPAIR %p invalid outer public key:\n%s\n",
1461 ipair, data );
1462 goto err_decode;
1463 }
1464
1465 /* Decode inner layer of Base64 */
1466 next = pem_asn1 ( decoded, len, 0, &key );
1467 if ( next < 0 ) {
1468 rc = next;
1469 DBGC ( ipair, "IPAIR %p invalid inner public key:\n%s\n",
1470 ipair, decoded );
1471 goto err_asn1;
1472 }
1473 DBGC ( ipair, "IPAIR %p received public key\n", ipair );
1474 DBGC2_HDA ( ipair, 0, key->data, key->len );
1475
1476 /* Construct certificates */
1477 if ( ( rc = icert_certs ( &ipair->icert, key ) ) != 0 )
1478 goto err_certs;
1479
1480 /* Send session request or pair request as applicable */
1481 if ( ipair->flags & IPAIR_REQUEST ) {
1484 } else {
1487 }
1489
1490 /* Free key */
1491 free ( key );
1492
1493 /* Free intermediate Base64 */
1494 free ( decoded );
1495
1496 return 0;
1497
1498 err_certs:
1499 free ( key );
1500 err_asn1:
1501 err_decode:
1502 free ( decoded );
1503 err_alloc:
1504 err_tag:
1505 return rc;
1506}
1507
1508/**
1509 * Transmit Pair message
1510 *
1511 * @v ipair Pairing client
1512 * @ret rc Return status code
1513 */
1514static int ipair_tx_pair ( struct ipair *ipair ) {
1515 char *root;
1516 char *host;
1517 char *device;
1518 int rc;
1519
1520 /* Construct doubly encoded certificates */
1521 if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.root,
1522 &root ) ) != 0 )
1523 goto err_root;
1524 if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.host,
1525 &host ) ) != 0 )
1526 goto err_host;
1527 if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.device,
1528 &device ) ) != 0 )
1529 goto err_device;
1530
1531 /* Transmit message */
1532 if ( ( rc = ipair_tx ( ipair,
1533 "%s"
1534 "<string>Pair</string>\n"
1535 "<key>PairRecord</key>\n"
1536 "<dict>\n"
1537 "<key>RootCertificate</key>\n"
1538 "<data>%s</data>\n"
1539 "<key>HostCertificate</key>\n"
1540 "<data>%s</data>\n"
1541 "<key>DeviceCertificate</key>\n"
1542 "<data>%s</data>\n"
1543 "<key>SystemBUID</key>\n"
1544 "<string>%s</string>\n"
1545 "<key>HostID</key>\n"
1546 "<string>%s</string>\n"
1547 "</dict>\n"
1548 "<key>ProtocolVersion</key>\n"
1549 "<string>2</string>\n"
1550 "<key>PairingOptions</key>\n"
1551 "<dict>\n"
1552 "<key>ExtendedPairingErrors</key>\n"
1553 "<true/>\n"
1554 "</dict>\n"
1555 "%s",
1556 ipair_prefix, root, host, device,
1559 ) ) != 0 )
1560 goto err_tx;
1561
1562 err_tx:
1563 free ( device );
1564 err_device:
1565 free ( host );
1566 err_host:
1567 free ( root );
1568 err_root:
1569 return rc;
1570}
1571
1572/**
1573 * Receive Pair message error
1574 *
1575 * @v ipair Pairing client
1576 * @v error Pairing error
1577 * @ret rc Return status code
1578 */
1579static int ipair_rx_pair_error ( struct ipair *ipair, char *error ) {
1580
1581 /* Check for actual errors */
1582 if ( strcmp ( error, "PairingDialogResponsePending" ) != 0 ) {
1583 DBGC ( ipair, "IPAIR %p pairing error \"%s\"\n", ipair, error );
1584 return -EPERM;
1585 }
1586
1587 /* Retransmit pairing request */
1591
1592 DBGC ( ipair, "IPAIR %p waiting for pairing dialog\n", ipair );
1593 return 0;
1594}
1595
1596/**
1597 * Receive Pair message
1598 *
1599 * @v ipair Pairing client
1600 * @v msg XML message
1601 * @ret rc Return status code
1602 */
1603static int ipair_rx_pair ( struct ipair *ipair, char *msg ) {
1604 char *error;
1605 char *escrow;
1606 char *end;
1607 int rc;
1608
1609 /* Check for pairing errors */
1610 if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1611 &end ) ) == 0 ) {
1612 *end = '\0';
1613 return ipair_rx_pair_error ( ipair, error );
1614 }
1615
1616 /* Get EscrowBag */
1617 if ( ( rc = ipair_key ( ipair, msg, "EscrowBag", "data", &escrow,
1618 &end ) ) != 0 ) {
1619 DBGC ( ipair, "IPAIR %p unexpected pairing response:\n%s\n",
1620 ipair, msg );
1621 return rc;
1622 }
1623 DBGC ( ipair, "IPAIR %p pairing successful\n", ipair );
1624
1625 /* Send session request */
1629
1630 return 0;
1631}
1632
1633/**
1634 * Transmit StartSession message
1635 *
1636 * @v ipair Pairing client
1637 * @ret rc Return status code
1638 */
1639static int ipair_tx_session ( struct ipair *ipair ) {
1640 int rc;
1641
1642 /* Transmit message */
1643 if ( ( rc = ipair_tx ( ipair,
1644 "%s"
1645 "<string>StartSession</string>\n"
1646 "<key>SystemBUID</key>\n"
1647 "<string>%s</string>\n"
1648 "<key>HostID</key>\n"
1649 "<string>%s</string>\n"
1650 "%s",
1653 ) ) != 0 )
1654 return rc;
1655
1656 return 0;
1657}
1658
1659/**
1660 * Receive StartSession message error
1661 *
1662 * @v ipair Pairing client
1663 * @v error Pairing error
1664 * @ret rc Return status code
1665 */
1666static int ipair_rx_session_error ( struct ipair *ipair, char *error ) {
1667
1668 /* Check for actual errors */
1669 if ( strcmp ( error, "InvalidHostID" ) != 0 ) {
1670 DBGC ( ipair, "IPAIR %p session error \"%s\"\n", ipair, error );
1671 return -EPERM;
1672 }
1673
1674 /* Transmit pairing request */
1678
1679 DBGC ( ipair, "IPAIR %p unknown host: requesting pairing\n", ipair );
1680 return 0;
1681}
1682
1683/**
1684 * Receive StartSession message
1685 *
1686 * @v ipair Pairing client
1687 * @v msg XML message
1688 * @ret rc Return status code
1689 */
1690static int ipair_rx_session ( struct ipair *ipair, char *msg ) {
1691 char *error;
1692 char *session;
1693 char *end;
1694 int rc;
1695
1696 /* Check for session errors */
1697 if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1698 &end ) ) == 0 ) {
1699 *end = '\0';
1701 }
1702
1703 /* Check for session ID */
1704 if ( ( rc = ipair_key ( ipair, msg, "SessionID", "string", &session,
1705 &end ) ) != 0 ) {
1706 DBGC ( ipair, "IPAIR %p unexpected session response:\n%s\n",
1707 ipair, msg );
1708 return rc;
1709 }
1710 *end = '\0';
1711 DBGC ( ipair, "IPAIR %p starting session \"%s\"\n", ipair, session );
1712
1713 /* Start TLS */
1714 if ( ( rc = add_tls ( &ipair->xfer, "iPhone", &icert_root,
1715 ipair->icert.key ) ) != 0 ) {
1716 DBGC ( ipair, "IPAIR %p could not start TLS: %s\n",
1717 ipair, strerror ( rc ) );
1718 return rc;
1719 }
1720
1721 /* Record that TLS has been started */
1722 ipair->flags |= IPAIR_TLS;
1723
1724 return 0;
1725}
1726
1727/**
1728 * Handle window change notification
1729 *
1730 * @v ipair Pairing client
1731 */
1732static void ipair_window_changed ( struct ipair *ipair ) {
1733
1734 /* Report pairing as complete once TLS session has been established */
1735 if ( ( ipair->flags & IPAIR_TLS ) && xfer_window ( &ipair->xfer ) ) {
1736
1737 /* Sanity checks */
1743
1744 /* Report pairing as complete */
1745 DBGC ( ipair, "IPAIR %p established TLS session\n", ipair );
1746 ipair_close ( ipair, 0 );
1747 return;
1748 }
1749}
1750
1751/**
1752 * Handle received data
1753 *
1754 * @v ipair Pairing client
1755 * @v iobuf I/O buffer
1756 * @v meta Data transfer metadata
1757 * @ret rc Return status code
1758 */
1759static int ipair_deliver ( struct ipair *ipair, struct io_buffer *iobuf,
1760 struct xfer_metadata *meta __unused ) {
1761 struct ipair_header *hdr;
1762 int rc;
1763
1764 /* Strip header (which may appear in a separate packet) */
1765 if ( ( ! ( ipair->flags & IPAIR_RX_LEN ) ) &&
1766 ( iob_len ( iobuf ) >= sizeof ( *hdr ) ) ) {
1767 iob_pull ( iobuf, sizeof ( *hdr ) );
1769 }
1770
1771 /* Clear received header flag if we have a message */
1772 if ( iob_len ( iobuf ) )
1774
1775 /* Receive message */
1776 if ( ( rc = ipair_rx ( ipair, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
1777 goto error;
1778
1779 /* Free I/O buffer */
1780 free_iob ( iobuf );
1781
1782 return 0;
1783
1784 error:
1785 ipair_close ( ipair, rc );
1786 free_iob ( iobuf );
1787 return rc;
1788}
1789
1790/**
1791 * Pairing transmission timer
1792 *
1793 * @v timer Retransmission timer
1794 * @v over Failure indicator
1795 */
1796static void ipair_expired ( struct retry_timer *timer, int over __unused ) {
1797 struct ipair *ipair = container_of ( timer, struct ipair, timer );
1798 int ( * tx ) ( struct ipair *ipair );
1799 int rc;
1800
1801 /* Sanity check */
1802 tx = ipair->tx;
1803 assert ( tx != NULL );
1804
1805 /* Clear pending transmission */
1806 ipair->tx = NULL;
1807
1808 /* Transmit data, if applicable */
1809 if ( ( rc = tx ( ipair ) ) != 0 )
1810 ipair_close ( ipair, rc );
1811}
1812
1813/** Pairing client interface operations */
1819
1820/** Pairing client interface descriptor */
1822 INTF_DESC ( struct ipair, xfer, ipair_xfer_operations );
1823
1824/**
1825 * Create a pairing client
1826 *
1827 * @v xfer Data transfer interface
1828 * @v flags Initial state flags
1829 * @ret rc Return status code
1830 */
1831static int ipair_create ( struct interface *xfer, unsigned int flags ) {
1832 struct ipair *ipair;
1833 int rc;
1834
1835 /* Allocate and initialise structure */
1836 ipair = zalloc ( sizeof ( *ipair ) );
1837 if ( ! ipair ) {
1838 rc = -ENOMEM;
1839 goto err_alloc;
1840 }
1843 timer_init ( &ipair->timer, ipair_expired, &ipair->refcnt );
1846 ipair->flags = flags;
1847
1848 /* Schedule initial transmission */
1850
1851 /* Attach to parent interface, mortalise self, and return */
1853 ref_put ( &ipair->refcnt );
1854 return 0;
1855
1856 ref_put ( &ipair->refcnt );
1857 err_alloc:
1858 return rc;
1859}
1860
1861/******************************************************************************
1862 *
1863 * iPhone USB networking
1864 *
1865 ******************************************************************************
1866 */
1867
1868/**
1869 * Complete bulk IN transfer
1870 *
1871 * @v ep USB endpoint
1872 * @v iobuf I/O buffer
1873 * @v rc Completion status code
1874 */
1875static void iphone_in_complete ( struct usb_endpoint *ep,
1876 struct io_buffer *iobuf, int rc ) {
1877 struct iphone *iphone = container_of ( ep, struct iphone, usbnet.in );
1878 struct net_device *netdev = iphone->netdev;
1879
1880 /* Profile receive completions */
1881 profile_start ( &iphone_in_profiler );
1882
1883 /* Ignore packets cancelled when the endpoint closes */
1884 if ( ! ep->open )
1885 goto ignore;
1886
1887 /* Record USB errors against the network device */
1888 if ( rc != 0 ) {
1889 DBGC ( iphone, "IPHONE %p bulk IN failed: %s\n",
1890 iphone, strerror ( rc ) );
1891 goto error;
1892 }
1893
1894 /* Strip padding */
1895 if ( iob_len ( iobuf ) < IPHONE_IN_PAD ) {
1896 DBGC ( iphone, "IPHONE %p malformed bulk IN:\n", iphone );
1897 DBGC_HDA ( iphone, 0, iobuf->data, iob_len ( iobuf ) );
1898 rc = -EINVAL;
1899 goto error;
1900 }
1901 iob_pull ( iobuf, IPHONE_IN_PAD );
1902
1903 /* Hand off to network stack */
1904 netdev_rx ( netdev, iob_disown ( iobuf ) );
1905
1906 profile_stop ( &iphone_in_profiler );
1907 return;
1908
1909 error:
1910 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
1911 ignore:
1912 free_iob ( iobuf );
1913}
1914
1915/** Bulk IN endpoint operations */
1919
1920/**
1921 * Transmit packet
1922 *
1923 * @v iphone iPhone device
1924 * @v iobuf I/O buffer
1925 * @ret rc Return status code
1926 */
1927static int iphone_out_transmit ( struct iphone *iphone,
1928 struct io_buffer *iobuf ) {
1929 int rc;
1930
1931 /* Profile transmissions */
1932 profile_start ( &iphone_out_profiler );
1933
1934 /* Enqueue I/O buffer */
1935 if ( ( rc = usb_stream ( &iphone->usbnet.out, iobuf, 1 ) ) != 0 )
1936 return rc;
1937
1938 profile_stop ( &iphone_out_profiler );
1939 return 0;
1940}
1941
1942/**
1943 * Complete bulk OUT transfer
1944 *
1945 * @v ep USB endpoint
1946 * @v iobuf I/O buffer
1947 * @v rc Completion status code
1948 */
1949static void iphone_out_complete ( struct usb_endpoint *ep,
1950 struct io_buffer *iobuf, int rc ) {
1951 struct iphone *iphone = container_of ( ep, struct iphone, usbnet.out );
1952 struct net_device *netdev = iphone->netdev;
1953
1954 /* Report TX completion */
1955 netdev_tx_complete_err ( netdev, iobuf, rc );
1956}
1957
1958/** Bulk OUT endpoint operations */
1962
1963/**
1964 * Check pairing status
1965 *
1966 * @v iphone iPhone device
1967 * @ret rc Return status code
1968 */
1969static int iphone_check_pair ( struct iphone *iphone ) {
1970 struct imux *imux;
1971
1972 /* Find corresponding USB multiplexer */
1973 list_for_each_entry ( imux, &imuxes, list ) {
1974 if ( imux->usb == iphone->usb )
1975 return imux->rc;
1976 }
1977
1978 return -EPIPE_NO_MUX;
1979}
1980
1981/**
1982 * Check link status
1983 *
1984 * @v netdev Network device
1985 */
1986static void iphone_check_link ( struct net_device *netdev ) {
1987 struct iphone *iphone = netdev->priv;
1988 struct usb_device *usb = iphone->usb;
1990 int rc;
1991
1992 /* Check pairing status */
1993 if ( ( rc = iphone_check_pair ( iphone ) ) != 0 )
1994 goto err_pair;
1995
1996 /* Get link status */
1997 if ( ( rc = usb_control ( usb, IPHONE_GET_LINK, 0, 0, &status,
1998 sizeof ( status ) ) ) != 0 ) {
1999 DBGC ( iphone, "IPHONE %p could not get link status: %s\n",
2000 iphone, strerror ( rc ) );
2001 goto err_control;
2002 }
2003
2004 /* Check link status */
2005 if ( status != IPHONE_LINK_UP ) {
2006 rc = -ENOTCONN_STATUS ( status );
2007 goto err_status;
2008 }
2009
2010 /* Success */
2011 rc = 0;
2012
2013 err_status:
2014 err_control:
2015 err_pair:
2016 /* Report link status. Since we have to check the link
2017 * periodically (due to an absence of an interrupt endpoint),
2018 * do this only if the link status has actually changed.
2019 */
2020 if ( rc != netdev->link_rc ) {
2021 if ( rc == 0 ) {
2022 DBGC ( iphone, "IPHONE %p link up\n", iphone );
2023 } else {
2024 DBGC ( iphone, "IPHONE %p link down: %s\n",
2025 iphone, strerror ( rc ) );
2026 }
2028 }
2029}
2030
2031/**
2032 * Periodically update link status
2033 *
2034 * @v timer Link status timer
2035 * @v over Failure indicator
2036 */
2037static void iphone_expired ( struct retry_timer *timer, int over __unused ) {
2038 struct iphone *iphone = container_of ( timer, struct iphone, timer );
2039 struct net_device *netdev = iphone->netdev;
2040
2041 /* Check link status */
2043
2044 /* Restart timer, if device is open */
2045 if ( netdev_is_open ( netdev ) )
2047}
2048
2049/**
2050 * Open network device
2051 *
2052 * @v netdev Network device
2053 * @ret rc Return status code
2054 */
2055static int iphone_open ( struct net_device *netdev ) {
2056 struct iphone *iphone = netdev->priv;
2057 int rc;
2058
2059 /* Open USB network device */
2060 if ( ( rc = usbnet_open ( &iphone->usbnet ) ) != 0 ) {
2061 DBGC ( iphone, "IPHONE %p could not open: %s\n",
2062 iphone, strerror ( rc ) );
2063 goto err_open;
2064 }
2065
2066 /* Start the link status check timer */
2068
2069 return 0;
2070
2072 err_open:
2073 return rc;
2074}
2075
2076/**
2077 * Close network device
2078 *
2079 * @v netdev Network device
2080 */
2081static void iphone_close ( struct net_device *netdev ) {
2082 struct iphone *iphone = netdev->priv;
2083
2084 /* Stop the link status check timer */
2085 stop_timer ( &iphone->timer );
2086
2087 /* Close USB network device */
2089}
2090
2091/**
2092 * Transmit packet
2093 *
2094 * @v netdev Network device
2095 * @v iobuf I/O buffer
2096 * @ret rc Return status code
2097 */
2098static int iphone_transmit ( struct net_device *netdev,
2099 struct io_buffer *iobuf ) {
2100 struct iphone *iphone = netdev->priv;
2101 int rc;
2102
2103 /* Transmit packet */
2104 if ( ( rc = iphone_out_transmit ( iphone, iobuf ) ) != 0 )
2105 return rc;
2106
2107 return 0;
2108}
2109
2110/**
2111 * Poll for completed and received packets
2112 *
2113 * @v netdev Network device
2114 */
2115static void iphone_poll ( struct net_device *netdev ) {
2116 struct iphone *iphone = netdev->priv;
2117 int rc;
2118
2119 /* Poll USB bus */
2120 usb_poll ( iphone->bus );
2121
2122 /* Refill endpoints */
2123 if ( ( rc = usbnet_refill ( &iphone->usbnet ) ) != 0 )
2125}
2126
2127/** iPhone network device operations */
2129 .open = iphone_open,
2130 .close = iphone_close,
2131 .transmit = iphone_transmit,
2132 .poll = iphone_poll,
2133};
2134
2135/**
2136 * Probe device
2137 *
2138 * @v func USB function
2139 * @v config Configuration descriptor
2140 * @ret rc Return status code
2141 */
2142static int iphone_probe ( struct usb_function *func,
2143 struct usb_configuration_descriptor *config ) {
2144 struct usb_device *usb = func->usb;
2145 struct net_device *netdev;
2146 struct iphone *iphone;
2147 int rc;
2148
2149 /* Allocate and initialise structure */
2150 netdev = alloc_etherdev ( sizeof ( *iphone ) );
2151 if ( ! netdev ) {
2152 rc = -ENOMEM;
2153 goto err_alloc;
2154 }
2156 netdev->dev = &func->dev;
2157 iphone = netdev->priv;
2158 memset ( iphone, 0, sizeof ( *iphone ) );
2159 iphone->usb = usb;
2160 iphone->bus = usb->port->hub->bus;
2161 iphone->netdev = netdev;
2166 timer_init ( &iphone->timer, iphone_expired, &netdev->refcnt );
2167 DBGC ( iphone, "IPHONE %p on %s\n", iphone, func->name );
2168
2169 /* Describe USB network device */
2170 if ( ( rc = usbnet_describe ( &iphone->usbnet, config ) ) != 0 ) {
2171 DBGC ( iphone, "IPHONE %p could not describe: %s\n",
2172 iphone, strerror ( rc ) );
2173 goto err_describe;
2174 }
2175
2176 /* Fetch MAC address */
2177 if ( ( rc = usb_control ( usb, IPHONE_GET_MAC, 0, 0, netdev->hw_addr,
2178 ETH_ALEN ) ) != 0 ) {
2179 DBGC ( iphone, "IPHONE %p could not fetch MAC address: %s\n",
2180 iphone, strerror ( rc ) );
2181 goto err_fetch_mac;
2182 }
2183
2184 /* Register network device */
2185 if ( ( rc = register_netdev ( netdev ) ) != 0 )
2186 goto err_register;
2187
2188 /* Set initial link status */
2190
2191 /* Add to list of iPhone network devices */
2192 list_add ( &iphone->list, &iphones );
2193
2194 usb_func_set_drvdata ( func, iphone );
2195 return 0;
2196
2197 list_del ( &iphone->list );
2199 err_register:
2200 err_fetch_mac:
2201 err_describe:
2203 netdev_put ( netdev );
2204 err_alloc:
2205 return rc;
2206}
2207
2208/**
2209 * Remove device
2210 *
2211 * @v func USB function
2212 */
2213static void iphone_remove ( struct usb_function *func ) {
2214 struct iphone *iphone = usb_func_get_drvdata ( func );
2215 struct net_device *netdev = iphone->netdev;
2216
2217 list_del ( &iphone->list );
2220 netdev_put ( netdev );
2221}
2222
2223/** iPhone device IDs */
2224static struct usb_device_id iphone_ids[] = {
2225 USB_ROM ( 0x05ac, 0xffff, "iphone", "iPhone", 0 ),
2226};
2227
2228/** iPhone driver */
2229struct usb_driver iphone_driver __usb_driver = {
2230 .ids = iphone_ids,
2231 .id_count = ( sizeof ( iphone_ids ) / sizeof ( iphone_ids[0] ) ),
2232 .class = USB_CLASS_ID ( 0xff, 0xfd, 0x01 ),
2233 .score = USB_SCORE_NORMAL,
2234 .probe = iphone_probe,
2235 .remove = iphone_remove,
2236};
2237
2238/* Drag in objects via iphone_driver */
2239REQUIRING_SYMBOL ( iphone_driver );
2240
2241/* Drag in RSA-with-SHA256 OID prefixes */
2242REQUIRE_OBJECT ( rsa_sha256 );
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
__be32 raw[7]
Definition CIB_PRM.h:0
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#define SHA256_DIGEST_SIZE
Definition Tpm20.h:30
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:972
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition asn1.c:949
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition asn1.c:999
#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:492
#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:322
#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:402
#define ASN1_OID_BASICCONSTRAINTS
ASN.1 OID for id-ce-basicConstraints (2.5.29.19)
Definition asn1.h:332
#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:327
#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:186
#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:50
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:265
Ethernet protocol.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGCP_HDA(...)
Definition compiler.h:540
#define DBGC2(...)
Definition compiler.h:522
#define DBGCP(...)
Definition compiler.h:539
#define DBGC2_HDA(...)
Definition compiler.h:523
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
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:896
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:202
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EPROTO
Protocol error.
Definition errno.h:625
#define EPIPE
Broken pipe.
Definition errno.h:620
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ECANCELED
Operation canceled.
Definition errno.h:344
#define EPERM
Operation not permitted.
Definition errno.h:615
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#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:219
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:230
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:224
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:301
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:1453
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:617
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1401
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1072
#define USB_ROM(_vendor, _product, _name, _description, _data)
Definition usb.h:1381
#define USB_ID(_vendor, _product, _name, _description, _data)
Definition usb.h:1373
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:707
@ USB_SCORE_NORMAL
Normal driver.
Definition usb.h:1465
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:718
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:89
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
#define iob_pull(iobuf, len)
Definition iobuf.h:107
static struct usb_device_id iphone_ids[]
iPhone device IDs
Definition iphone.c:2224
static struct interface_operation ipair_xfer_operations[]
Pairing client interface operations.
Definition iphone.c:1814
static void imux_shutdown(struct imux *imux)
Shut down USB multiplexer.
Definition iphone.c:955
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:1016
static int ipair_tx_pair(struct ipair *ipair)
Transmit Pair message.
Definition iphone.c:1514
static int ipair_create(struct interface *xfer, unsigned int flags)
Create a pairing client.
Definition iphone.c:1831
static int ipair_tag(struct ipair *ipair, const char *msg, const char *tag, char **start, char **end)
Locate XML tag.
Definition iphone.c:1346
static const char ipair_suffix[]
Common suffix for all pairing messages.
Definition iphone.c:1207
static int ipair_rx_session_error(struct ipair *ipair, char *error)
Receive StartSession message error.
Definition iphone.c:1666
static int ipair_rx_pair_error(struct ipair *ipair, char *error)
Receive Pair message error.
Definition iphone.c:1579
static int ipair_tx_pubkey(struct ipair *ipair)
Transmit DevicePublicKey message.
Definition iphone.c:1408
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:1380
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:2115
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:1603
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:2142
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:1242
static struct usb_endpoint_driver_operations imux_out_operations
Bulk OUT endpoint operations.
Definition iphone.c:946
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:1165
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:930
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:1054
static int iphone_open(struct net_device *netdev)
Open network device.
Definition iphone.c:2055
static int ipair_tx(struct ipair *ipair, const char *fmt,...)
Transmit XML message.
Definition iphone.c:1260
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:919
static int iphone_out_transmit(struct iphone *iphone, struct io_buffer *iobuf)
Transmit packet.
Definition iphone.c:1927
static const char ipair_host_id[]
Arbitrary host ID used for pairing.
Definition iphone.c:1215
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:1229
static int ipair_tx_session(struct ipair *ipair)
Transmit StartSession message.
Definition iphone.c:1639
static struct usb_endpoint_driver_operations iphone_out_operations
Bulk OUT endpoint operations.
Definition iphone.c:1959
static void iphone_remove(struct usb_function *func)
Remove device.
Definition iphone.c:2213
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:2037
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:1196
static void imux_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition iphone.c:867
#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:1304
static int ipair_rx_session(struct ipair *ipair, char *msg)
Receive StartSession message.
Definition iphone.c:1690
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:1212
static void iphone_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition iphone.c:1875
static struct interface_descriptor ipair_xfer_desc
Pairing client interface descriptor.
Definition iphone.c:1821
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:1431
static void iphone_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition iphone.c:1949
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:1061
static int ipair_deliver(struct ipair *ipair, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle received data.
Definition iphone.c:1759
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:2098
static void imux_step(struct imux *imux)
Multiplexer process.
Definition iphone.c:1069
static void iphone_close(struct net_device *netdev)
Close network device.
Definition iphone.c:2081
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:1040
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:1732
static void imux_close(struct imux *imux, int rc)
Close USB multiplexer.
Definition iphone.c:973
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:2128
#define ENOTCONN_STATUS(status)
Definition iphone.c:64
static struct usb_endpoint_driver_operations iphone_in_operations
Bulk IN endpoint operations.
Definition iphone.c:1916
static int imux_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition iphone.c:1104
static struct usb_device_id imux_ids[]
USB multiplexer device IDs.
Definition iphone.c:1174
static struct process_descriptor imux_process_desc
Multiplexer process descriptor.
Definition iphone.c:1094
static void iphone_check_link(struct net_device *netdev)
Check link status.
Definition iphone.c:1986
static int iphone_check_pair(struct iphone *iphone)
Check pairing status.
Definition iphone.c:1969
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:1796
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:662
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
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:942
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:662
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
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:661
RSA public-key cryptography.
struct digest_algorithm sha256_algorithm
SHA-256 algorithm.
Definition sha256.c:265
SHA-256 algorithm.
#define SHA256_CTX_SIZE
SHA-256 context size.
Definition sha256.h:72
#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:310
char * strcpy(char *dest, const char *src)
Copy string.
Definition string.c:347
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:38
void * data
Start of data.
Definition iobuf.h:53
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:122
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:1361
A USB device.
Definition usb.h:723
struct usb_port * port
USB port.
Definition usb.h:727
A USB driver.
Definition usb.h:1419
USB endpoint driver operations.
Definition usb.h:489
A USB endpoint.
Definition usb.h:404
int open
Endpoint is open.
Definition usb.h:419
A USB function.
Definition usb.h:674
struct usb_device * usb
USB device.
Definition usb.h:678
struct device dev
Generic device.
Definition usb.h:682
const char * name
Name.
Definition usb.h:676
struct usb_bus * bus
USB bus.
Definition usb.h:845
struct usb_hub * hub
USB hub.
Definition usb.h:815
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:3962
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:784
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition usb.c:546
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:465
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