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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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 
68 static int ipair_create ( struct interface *xfer, unsigned int flags );
69 
70 /** Bulk IN completion profiler */
71 static struct profiler iphone_in_profiler __profiler =
72  { .name = "iphone.in" };
73 
74 /** Bulk OUT profiler */
75 static struct profiler iphone_out_profiler __profiler =
76  { .name = "iphone.out" };
77 
78 /** List of USB multiplexers */
79 static LIST_HEAD ( imuxes );
80 
81 /** List of iPhone network devices */
82 static 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 */
95 static struct x509_root icert_root = {
97  .digest = &sha256_algorithm,
98  .count = 1,
99  .fingerprints = icert_root_fingerprint,
100 };
101 
102 /** Single zero byte used in constructed certificates */
103 static const uint8_t icert_nul[] = { 0x00 };
104 
105 /** "RSA algorithm" identifier used in constructed certificates */
106 static const uint8_t icert_rsa[] = {
107  /* algorithm */
110  ASN1_NULL, 0x00 )
111 };
112 
113 /** "SHA-256 with RSA algorithm" identifier used in constructed certificates */
114 static const uint8_t icert_sha256_rsa[] = {
117  ASN1_NULL, 0x00 ),
118 };
119 
120 /** Extensions used in constructed root certificate */
121 static const uint8_t icert_root_exts_data[] = {
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 */
142 static const uint8_t icert_leaf_exts_data[] = {
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 */
164  ASN1_SHORT ( ASN1_BIT_STRING, 0x07,
167  0x00 ) ) ) ) )
168 };
169 
170 /** Extensions used in constructed leaf certificates */
173 
174 /** "TBSCertificate" prefix in constructed certificates */
175 static const uint8_t icert_tbs_prefix[] = {
176  /* version */
178  /* serialNumber */
179  ASN1_SHORT ( ASN1_INTEGER, 0 ),
180  /* signature */
183  ASN1_NULL, 0x00 )
184 };
185 
186 /** Validity period in constructed certificates */
187 static 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 */
201 static const uint8_t icert_name_root_data[] = {
205  ASN1_SHORT ( ASN1_UTF8_STRING, 'R', 'o', 'o', 't' ) ) ) )
206 };
207 
208 /** "Root" subject name */
211 
212 /** "iPXE" subject name */
213 static const uint8_t icert_name_ipxe_data[] = {
217  ASN1_SHORT ( ASN1_UTF8_STRING, 'i', 'P', 'X', 'E' ) ) ) )
218 };
219 
220 /** "iPXE" subject name */
223 
224 /** "iPhone" subject name */
225 static const uint8_t icert_name_iphone_data[] = {
230  'i', 'P', 'h', 'o', 'n', 'e' ) ) ) )
231 };
232 
233 /** "iPhone" subject name */
236 
237 /** Public key(s) used for pairing */
238 static 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 };
252 static 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  */
283 static 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 };
296 static 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 */
321 static const char icert_begin[] = "-----BEGIN CERTIFICATE-----\n";
322 
323 /** PEM certificate suffix */
324 static const char icert_end[] = "\n-----END CERTIFICATE-----\n";
325 
326 /**
327  * Free pairing certificates
328  *
329  * @v icert Pairing certificates
330  */
331 static 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  */
355 static 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 ),
370  asn1_prepend_raw ( &spki, icert_nul,
371  sizeof ( icert_nul ) ),
372  asn1_wrap ( &spki, ASN1_BIT_STRING ),
373  asn1_prepend_raw ( &spki, icert_rsa,
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  */
448 static 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  }
463  privkey_init ( icert->key );
464  private = &icert->key->builder;
465 
466  /* Construct our "private" key */
467  if ( ( rc = ( asn1_prepend_raw ( private, icert_private,
468  sizeof ( icert_private ) ),
469  asn1_prepend_raw ( private, icert_public,
470  sizeof ( icert_public ) ),
471  asn1_prepend ( private, ASN1_INTEGER, icert_nul,
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  */
531 static 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  */
601 static 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  */
634 static 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  */
663 static 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 );
672  tcp->tcp.dest = htons ( IMUX_PORT_LOCKDOWND );
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  */
694 static 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  */
725 static 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  */
743 static 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  */
759 static 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  */
794 static 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  */
809 static 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  */
867 static 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 ):
899  imux_rx_version ( imux );
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 */
921 };
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  */
930 static 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 */
948 };
949 
950 /**
951  * Shut down USB multiplexer
952  *
953  * @v imux USB multiplexer
954  */
955 static 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 ) ) {
962  process_del ( &imux->process );
963  usbnet_close ( &imux->usbnet );
964  }
965 }
966 
967 /**
968  * Close USB multiplexer
969  *
970  * @v imux USB multiplexer
971  * @v rc Reason for close
972  */
973 static 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  */
1016 static 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  */
1040 static 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 ),
1056  INTF_OP ( xfer_alloc_iob, struct imux *, imux_alloc_iob ),
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  */
1069 static 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  */
1104 static 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  */
1165 static 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 */
1174 static struct usb_device_id imux_ids[] = {
1175  {
1176  .name = "imux",
1177  .vendor = 0x05ac,
1178  .product = USB_ANY_ID,
1179  },
1180 };
1181 
1182 /** USB multiplexer driver */
1183 struct usb_driver imux_driver __usb_driver = {
1184  .ids = imux_ids,
1185  .id_count = ( sizeof ( imux_ids ) / sizeof ( imux_ids[0] ) ),
1186  .class = USB_CLASS_ID ( 0xff, 0xfe, 0x02 ),
1187  .score = USB_SCORE_NORMAL,
1188  .probe = imux_probe,
1189  .remove = imux_remove,
1190 };
1191 
1192 /******************************************************************************
1193  *
1194  * iPhone pairing client
1195  *
1196  ******************************************************************************
1197  */
1198 
1199 /** Common prefix for all pairing messages */
1200 static const char ipair_prefix[] =
1201  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1202  "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
1203  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
1204  "<plist version=\"1.0\">\n"
1205  "<dict>\n"
1206  "<key>Label</key>\n"
1207  "<string>iPXE</string>\n"
1208  "<key>Request</key>\n";
1209 
1210 /** Common suffix for all pairing messages */
1211 static const char ipair_suffix[] =
1212  "</dict>\n"
1213  "</plist>\n";
1214 
1215 /** Arbitrary system BUID used for pairing */
1216 static const char ipair_system_buid[] = "E4DB92D2-248A-469A-AC34-92045D07E695";
1217 
1218 /** Arbitrary host ID used for pairing */
1219 static const char ipair_host_id[] = "93CEBC27-8457-4804-9108-F42549DF6143";
1220 
1221 static int ipair_tx_pubkey ( struct ipair *ipair );
1222 static int ipair_rx_pubkey ( struct ipair *ipair, char *msg );
1223 static int ipair_tx_pair ( struct ipair *ipair );
1224 static int ipair_rx_pair ( struct ipair *ipair, char *msg );
1225 static int ipair_tx_session ( struct ipair *ipair );
1226 static int ipair_rx_session ( struct ipair *ipair, char *msg );
1227 
1228 /**
1229  * Free pairing client
1230  *
1231  * @v refcnt Reference counter
1232  */
1233 static void ipair_free ( struct refcnt *refcnt ) {
1234  struct ipair *ipair = container_of ( refcnt, struct ipair, refcnt );
1235 
1236  icert_free ( &ipair->icert );
1237  free ( ipair );
1238 }
1239 
1240 /**
1241  * Shut down pairing client
1242  *
1243  * @v ipair Pairing client
1244  * @v rc Reason for close
1245  */
1246 static void ipair_close ( struct ipair *ipair, int rc ) {
1247 
1248  /* Shut down interfaces */
1249  intf_shutdown ( &ipair->xfer, rc );
1250 
1251  /* Stop timer */
1252  stop_timer ( &ipair->timer );
1253 }
1254 
1255 /**
1256  * Transmit XML message
1257  *
1258  * @v ipair Pairing client
1259  * @v fmt Format string
1260  * @v ... Arguments
1261  * @ret rc Return status code
1262  */
1263 static int __attribute__ (( format ( printf, 2, 3 ) ))
1264 ipair_tx ( struct ipair *ipair, const char *fmt, ... ) {
1265  struct io_buffer *iobuf;
1266  struct ipair_header *hdr;
1267  va_list args;
1268  size_t len;
1269  char *msg;
1270  int rc;
1271 
1272  /* Calculate length of formatted string */
1273  va_start ( args, fmt );
1274  len = ( vsnprintf ( NULL, 0, fmt, args ) + 1 /* NUL */ );
1275  va_end ( args );
1276 
1277  /* Allocate I/O buffer */
1278  iobuf = xfer_alloc_iob ( &ipair->xfer, ( sizeof ( *hdr ) + len ) );
1279  if ( ! iobuf )
1280  return -ENOMEM;
1281  hdr = iob_put ( iobuf, sizeof ( *hdr ) );
1282 
1283  /* Construct XML message */
1284  memset ( hdr, 0, sizeof ( *hdr ) );
1285  hdr->len = htonl ( len );
1286  msg = iob_put ( iobuf, len );
1287  va_start ( args, fmt );
1288  vsnprintf ( msg, len, fmt, args );
1289  va_end ( args );
1290  DBGC2 ( ipair, "IPAIR %p transmitting:\n%s\n", ipair, msg );
1291 
1292  /* Transmit message */
1293  if ( ( rc = xfer_deliver_iob ( &ipair->xfer,
1294  iob_disown ( iobuf ) ) ) != 0 )
1295  return rc;
1296 
1297  return 0;
1298 }
1299 
1300 /**
1301  * Receive XML message payload
1302  *
1303  * @v ipair Pairing client
1304  * @v msg Message payload
1305  * @v len Length of message
1306  * @ret rc Return status code
1307  */
1308 static int ipair_rx ( struct ipair *ipair, char *msg, size_t len ) {
1309  int ( * rx ) ( struct ipair *ipair, char *msg );
1310  int rc;
1311 
1312  /* Ignore empty messages */
1313  if ( ! len )
1314  return 0;
1315 
1316  /* Sanity check */
1317  if ( ( msg[ len - 1 ] != '\0' ) && ( msg[ len - 1 ] != '\n' ) ) {
1318  DBGC ( ipair, "IPAIR %p malformed XML:\n", ipair );
1319  DBGC_HDA ( ipair, 0, msg, len );
1320  return -EPROTO;
1321  }
1322 
1323  /* Add NUL terminator (potentially overwriting final newline) */
1324  msg[ len - 1 ] = '\0';
1325  DBGC2 ( ipair, "IPAIR %p received:\n%s\n\n", ipair, msg );
1326 
1327  /* Handle according to current state */
1328  rx = ipair->rx;
1329  if ( ! rx ) {
1330  DBGC ( ipair, "IPAIR %p unexpected XML:\n%s\n", ipair, msg );
1331  return -EPROTO;
1332  }
1333  ipair->rx = NULL;
1334  if ( ( rc = rx ( ipair, msg ) ) != 0 )
1335  return rc;
1336 
1337  return 0;
1338 }
1339 
1340 /**
1341  * Locate XML tag
1342  *
1343  * @v ipair Pairing client
1344  * @v msg XML message
1345  * @v tag Tag name
1346  * @ret start Start of tag content
1347  * @ret end End of tag content
1348  * @ret rc Return status code
1349  */
1350 static int ipair_tag ( struct ipair *ipair, const char *msg, const char *tag,
1351  char **start, char **end ) {
1352  char buf[ 2 /* "</" */ + strlen ( tag ) + 1 /* ">" */ + 1 /* NUL */ ];
1353 
1354  /* Locate opening tag */
1355  sprintf ( buf, "<%s>", tag );
1356  *start = strstr ( msg, buf );
1357  if ( ! *start )
1358  return -ENOENT;
1359  *start += strlen ( buf );
1360 
1361  /* Locate closing tag */
1362  sprintf ( buf, "</%s>", tag );
1363  *end = strstr ( *start, buf );
1364  if ( ! *end ) {
1365  DBGC ( ipair, "IPAIR %p missing closing tag %s in:\n%s\n",
1366  ipair, buf, msg );
1367  return -ENOENT;
1368  }
1369 
1370  return 0;
1371 }
1372 
1373 /**
1374  * Locate XML property list dictionary value
1375  *
1376  * @v ipair Pairing client
1377  * @v msg XML message
1378  * @v key Key name
1379  * @v type Key type
1380  * @ret start Start of value content
1381  * @ret end End of value content
1382  * @ret rc Return status code
1383  */
1384 static int ipair_key ( struct ipair *ipair, const char *msg, const char *key,
1385  const char *type, char **start, char **end ) {
1386  int rc;
1387 
1388  /* Iterate over keys */
1389  while ( 1 ) {
1390 
1391  /* Locate key */
1392  if ( ( rc = ipair_tag ( ipair, msg, "key", start,
1393  end ) ) != 0 )
1394  return rc;
1395  msg = *end;
1396 
1397  /* Check key name */
1398  if ( memcmp ( *start, key, ( *end - *start ) ) != 0 )
1399  continue;
1400 
1401  /* Locate value */
1402  return ipair_tag ( ipair, msg, type, start, end );
1403  }
1404 }
1405 
1406 /**
1407  * Transmit DevicePublicKey message
1408  *
1409  * @v ipair Pairing client
1410  * @ret rc Return status code
1411  */
1412 static int ipair_tx_pubkey ( struct ipair *ipair ) {
1413  int rc;
1414 
1415  /* Transmit message */
1416  if ( ( rc = ipair_tx ( ipair,
1417  "%s"
1418  "<string>GetValue</string>\n"
1419  "<key>Key</key>\n"
1420  "<string>DevicePublicKey</string>\n"
1421  "%s",
1422  ipair_prefix, ipair_suffix ) ) != 0 )
1423  return rc;
1424 
1425  return 0;
1426 }
1427 
1428 /**
1429  * Receive DevicePublicKey message
1430  *
1431  * @v ipair Pairing client
1432  * @v msg XML message
1433  * @ret rc Return status code
1434  */
1435 static int ipair_rx_pubkey ( struct ipair *ipair, char *msg ) {
1436  struct asn1_cursor *key;
1437  char *data;
1438  char *end;
1439  char *decoded;
1440  size_t max_len;
1441  int len;
1442  int next;
1443  int rc;
1444 
1445  /* Locate "Value" value */
1446  if ( ( rc = ipair_key ( ipair, msg, "Value", "data", &data,
1447  &end ) ) != 0 ) {
1448  DBGC ( ipair, "IPAIR %p unexpected public key message:\n%s\n",
1449  ipair, msg );
1450  goto err_tag;
1451  }
1452  *end = '\0';
1453 
1454  /* Decode outer layer of Base64 */
1455  max_len = base64_decoded_max_len ( data );
1456  decoded = malloc ( max_len );
1457  if ( ! decoded ) {
1458  rc = -ENOMEM;
1459  goto err_alloc;
1460  }
1461  len = base64_decode ( data, decoded, max_len );
1462  if ( len < 0 ) {
1463  rc = len;
1464  DBGC ( ipair, "IPAIR %p invalid outer public key:\n%s\n",
1465  ipair, data );
1466  goto err_decode;
1467  }
1468 
1469  /* Decode inner layer of Base64 */
1470  next = pem_asn1 ( decoded, len, 0, &key );
1471  if ( next < 0 ) {
1472  rc = next;
1473  DBGC ( ipair, "IPAIR %p invalid inner public key:\n%s\n",
1474  ipair, decoded );
1475  goto err_asn1;
1476  }
1477  DBGC ( ipair, "IPAIR %p received public key\n", ipair );
1478  DBGC2_HDA ( ipair, 0, key->data, key->len );
1479 
1480  /* Construct certificates */
1481  if ( ( rc = icert_certs ( &ipair->icert, key ) ) != 0 )
1482  goto err_certs;
1483 
1484  /* Send session request or pair request as applicable */
1485  if ( ipair->flags & IPAIR_REQUEST ) {
1486  ipair->tx = ipair_tx_pair;
1487  ipair->rx = ipair_rx_pair;
1488  } else {
1491  }
1493 
1494  /* Free key */
1495  free ( key );
1496 
1497  /* Free intermediate Base64 */
1498  free ( decoded );
1499 
1500  return 0;
1501 
1502  err_certs:
1503  free ( key );
1504  err_asn1:
1505  err_decode:
1506  free ( decoded );
1507  err_alloc:
1508  err_tag:
1509  return rc;
1510 }
1511 
1512 /**
1513  * Transmit Pair message
1514  *
1515  * @v ipair Pairing client
1516  * @ret rc Return status code
1517  */
1518 static int ipair_tx_pair ( struct ipair *ipair ) {
1519  char *root;
1520  char *host;
1521  char *device;
1522  int rc;
1523 
1524  /* Construct doubly encoded certificates */
1525  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.root,
1526  &root ) ) != 0 )
1527  goto err_root;
1528  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.host,
1529  &host ) ) != 0 )
1530  goto err_host;
1531  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.device,
1532  &device ) ) != 0 )
1533  goto err_device;
1534 
1535  /* Transmit message */
1536  if ( ( rc = ipair_tx ( ipair,
1537  "%s"
1538  "<string>Pair</string>\n"
1539  "<key>PairRecord</key>\n"
1540  "<dict>\n"
1541  "<key>RootCertificate</key>\n"
1542  "<data>%s</data>\n"
1543  "<key>HostCertificate</key>\n"
1544  "<data>%s</data>\n"
1545  "<key>DeviceCertificate</key>\n"
1546  "<data>%s</data>\n"
1547  "<key>SystemBUID</key>\n"
1548  "<string>%s</string>\n"
1549  "<key>HostID</key>\n"
1550  "<string>%s</string>\n"
1551  "</dict>\n"
1552  "<key>ProtocolVersion</key>\n"
1553  "<string>2</string>\n"
1554  "<key>PairingOptions</key>\n"
1555  "<dict>\n"
1556  "<key>ExtendedPairingErrors</key>\n"
1557  "<true/>\n"
1558  "</dict>\n"
1559  "%s",
1560  ipair_prefix, root, host, device,
1562  ipair_suffix
1563  ) ) != 0 )
1564  goto err_tx;
1565 
1566  err_tx:
1567  free ( device );
1568  err_device:
1569  free ( host );
1570  err_host:
1571  free ( root );
1572  err_root:
1573  return rc;
1574 }
1575 
1576 /**
1577  * Receive Pair message error
1578  *
1579  * @v ipair Pairing client
1580  * @v error Pairing error
1581  * @ret rc Return status code
1582  */
1583 static int ipair_rx_pair_error ( struct ipair *ipair, char *error ) {
1584 
1585  /* Check for actual errors */
1586  if ( strcmp ( error, "PairingDialogResponsePending" ) != 0 ) {
1587  DBGC ( ipair, "IPAIR %p pairing error \"%s\"\n", ipair, error );
1588  return -EPERM;
1589  }
1590 
1591  /* Retransmit pairing request */
1592  ipair->tx = ipair_tx_pair;
1593  ipair->rx = ipair_rx_pair;
1595 
1596  DBGC ( ipair, "IPAIR %p waiting for pairing dialog\n", ipair );
1597  return 0;
1598 }
1599 
1600 /**
1601  * Receive Pair message
1602  *
1603  * @v ipair Pairing client
1604  * @v msg XML message
1605  * @ret rc Return status code
1606  */
1607 static int ipair_rx_pair ( struct ipair *ipair, char *msg ) {
1608  char *error;
1609  char *escrow;
1610  char *end;
1611  int rc;
1612 
1613  /* Check for pairing errors */
1614  if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1615  &end ) ) == 0 ) {
1616  *end = '\0';
1617  return ipair_rx_pair_error ( ipair, error );
1618  }
1619 
1620  /* Get EscrowBag */
1621  if ( ( rc = ipair_key ( ipair, msg, "EscrowBag", "data", &escrow,
1622  &end ) ) != 0 ) {
1623  DBGC ( ipair, "IPAIR %p unexpected pairing response:\n%s\n",
1624  ipair, msg );
1625  return rc;
1626  }
1627  DBGC ( ipair, "IPAIR %p pairing successful\n", ipair );
1628 
1629  /* Send session request */
1633 
1634  return 0;
1635 }
1636 
1637 /**
1638  * Transmit StartSession message
1639  *
1640  * @v ipair Pairing client
1641  * @ret rc Return status code
1642  */
1643 static int ipair_tx_session ( struct ipair *ipair ) {
1644  int rc;
1645 
1646  /* Transmit message */
1647  if ( ( rc = ipair_tx ( ipair,
1648  "%s"
1649  "<string>StartSession</string>\n"
1650  "<key>SystemBUID</key>\n"
1651  "<string>%s</string>\n"
1652  "<key>HostID</key>\n"
1653  "<string>%s</string>\n"
1654  "%s",
1657  ) ) != 0 )
1658  return rc;
1659 
1660  return 0;
1661 }
1662 
1663 /**
1664  * Receive StartSession message error
1665  *
1666  * @v ipair Pairing client
1667  * @v error Pairing error
1668  * @ret rc Return status code
1669  */
1670 static int ipair_rx_session_error ( struct ipair *ipair, char *error ) {
1671 
1672  /* Check for actual errors */
1673  if ( strcmp ( error, "InvalidHostID" ) != 0 ) {
1674  DBGC ( ipair, "IPAIR %p session error \"%s\"\n", ipair, error );
1675  return -EPERM;
1676  }
1677 
1678  /* Transmit pairing request */
1679  ipair->tx = ipair_tx_pair;
1680  ipair->rx = ipair_rx_pair;
1682 
1683  DBGC ( ipair, "IPAIR %p unknown host: requesting pairing\n", ipair );
1684  return 0;
1685 }
1686 
1687 /**
1688  * Receive StartSession message
1689  *
1690  * @v ipair Pairing client
1691  * @v msg XML message
1692  * @ret rc Return status code
1693  */
1694 static int ipair_rx_session ( struct ipair *ipair, char *msg ) {
1695  char *error;
1696  char *session;
1697  char *end;
1698  int rc;
1699 
1700  /* Check for session errors */
1701  if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1702  &end ) ) == 0 ) {
1703  *end = '\0';
1704  return ipair_rx_session_error ( ipair, error );
1705  }
1706 
1707  /* Check for session ID */
1708  if ( ( rc = ipair_key ( ipair, msg, "SessionID", "string", &session,
1709  &end ) ) != 0 ) {
1710  DBGC ( ipair, "IPAIR %p unexpected session response:\n%s\n",
1711  ipair, msg );
1712  return rc;
1713  }
1714  *end = '\0';
1715  DBGC ( ipair, "IPAIR %p starting session \"%s\"\n", ipair, session );
1716 
1717  /* Start TLS */
1718  if ( ( rc = add_tls ( &ipair->xfer, "iPhone", &icert_root,
1719  ipair->icert.key ) ) != 0 ) {
1720  DBGC ( ipair, "IPAIR %p could not start TLS: %s\n",
1721  ipair, strerror ( rc ) );
1722  return rc;
1723  }
1724 
1725  /* Record that TLS has been started */
1726  ipair->flags |= IPAIR_TLS;
1727 
1728  return 0;
1729 }
1730 
1731 /**
1732  * Handle window change notification
1733  *
1734  * @v ipair Pairing client
1735  */
1736 static void ipair_window_changed ( struct ipair *ipair ) {
1737 
1738  /* Report pairing as complete once TLS session has been established */
1739  if ( ( ipair->flags & IPAIR_TLS ) && xfer_window ( &ipair->xfer ) ) {
1740 
1741  /* Sanity checks */
1744  assert ( ! x509_is_valid ( ipair->icert.root, NULL ) );
1745  assert ( ! x509_is_valid ( ipair->icert.host, NULL ) );
1746  assert ( ! x509_is_valid ( ipair->icert.device, NULL ) );
1747 
1748  /* Report pairing as complete */
1749  DBGC ( ipair, "IPAIR %p established TLS session\n", ipair );
1750  ipair_close ( ipair, 0 );
1751  return;
1752  }
1753 }
1754 
1755 /**
1756  * Handle received data
1757  *
1758  * @v ipair Pairing client
1759  * @v iobuf I/O buffer
1760  * @v meta Data transfer metadata
1761  * @ret rc Return status code
1762  */
1763 static int ipair_deliver ( struct ipair *ipair, struct io_buffer *iobuf,
1764  struct xfer_metadata *meta __unused ) {
1765  struct ipair_header *hdr;
1766  int rc;
1767 
1768  /* Strip header (which may appear in a separate packet) */
1769  if ( ( ! ( ipair->flags & IPAIR_RX_LEN ) ) &&
1770  ( iob_len ( iobuf ) >= sizeof ( *hdr ) ) ) {
1771  iob_pull ( iobuf, sizeof ( *hdr ) );
1772  ipair->flags |= IPAIR_RX_LEN;
1773  }
1774 
1775  /* Clear received header flag if we have a message */
1776  if ( iob_len ( iobuf ) )
1777  ipair->flags &= ~IPAIR_RX_LEN;
1778 
1779  /* Receive message */
1780  if ( ( rc = ipair_rx ( ipair, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
1781  goto error;
1782 
1783  /* Free I/O buffer */
1784  free_iob ( iobuf );
1785 
1786  return 0;
1787 
1788  error:
1789  ipair_close ( ipair, rc );
1790  free_iob ( iobuf );
1791  return rc;
1792 }
1793 
1794 /**
1795  * Pairing transmission timer
1796  *
1797  * @v timer Retransmission timer
1798  * @v over Failure indicator
1799  */
1800 static void ipair_expired ( struct retry_timer *timer, int over __unused ) {
1801  struct ipair *ipair = container_of ( timer, struct ipair, timer );
1802  int ( * tx ) ( struct ipair *ipair );
1803  int rc;
1804 
1805  /* Sanity check */
1806  tx = ipair->tx;
1807  assert ( tx != NULL );
1808 
1809  /* Clear pending transmission */
1810  ipair->tx = NULL;
1811 
1812  /* Transmit data, if applicable */
1813  if ( ( rc = tx ( ipair ) ) != 0 )
1814  ipair_close ( ipair, rc );
1815 }
1816 
1817 /** Pairing client interface operations */
1819  INTF_OP ( xfer_deliver, struct ipair *, ipair_deliver ),
1821  INTF_OP ( intf_close, struct ipair *, ipair_close ),
1822 };
1823 
1824 /** Pairing client interface descriptor */
1826  INTF_DESC ( struct ipair, xfer, ipair_xfer_operations );
1827 
1828 /**
1829  * Create a pairing client
1830  *
1831  * @v xfer Data transfer interface
1832  * @v flags Initial state flags
1833  * @ret rc Return status code
1834  */
1835 static int ipair_create ( struct interface *xfer, unsigned int flags ) {
1836  struct ipair *ipair;
1837  int rc;
1838 
1839  /* Allocate and initialise structure */
1840  ipair = zalloc ( sizeof ( *ipair ) );
1841  if ( ! ipair ) {
1842  rc = -ENOMEM;
1843  goto err_alloc;
1844  }
1847  timer_init ( &ipair->timer, ipair_expired, &ipair->refcnt );
1850  ipair->flags = flags;
1851 
1852  /* Schedule initial transmission */
1854 
1855  /* Attach to parent interface, mortalise self, and return */
1856  intf_plug_plug ( &ipair->xfer, xfer );
1857  ref_put ( &ipair->refcnt );
1858  return 0;
1859 
1860  ref_put ( &ipair->refcnt );
1861  err_alloc:
1862  return rc;
1863 }
1864 
1865 /******************************************************************************
1866  *
1867  * iPhone USB networking
1868  *
1869  ******************************************************************************
1870  */
1871 
1872 /**
1873  * Complete bulk IN transfer
1874  *
1875  * @v ep USB endpoint
1876  * @v iobuf I/O buffer
1877  * @v rc Completion status code
1878  */
1879 static void iphone_in_complete ( struct usb_endpoint *ep,
1880  struct io_buffer *iobuf, int rc ) {
1881  struct iphone *iphone = container_of ( ep, struct iphone, usbnet.in );
1882  struct net_device *netdev = iphone->netdev;
1883 
1884  /* Profile receive completions */
1885  profile_start ( &iphone_in_profiler );
1886 
1887  /* Ignore packets cancelled when the endpoint closes */
1888  if ( ! ep->open )
1889  goto ignore;
1890 
1891  /* Record USB errors against the network device */
1892  if ( rc != 0 ) {
1893  DBGC ( iphone, "IPHONE %p bulk IN failed: %s\n",
1894  iphone, strerror ( rc ) );
1895  goto error;
1896  }
1897 
1898  /* Strip padding */
1899  if ( iob_len ( iobuf ) < IPHONE_IN_PAD ) {
1900  DBGC ( iphone, "IPHONE %p malformed bulk IN:\n", iphone );
1901  DBGC_HDA ( iphone, 0, iobuf->data, iob_len ( iobuf ) );
1902  rc = -EINVAL;
1903  goto error;
1904  }
1905  iob_pull ( iobuf, IPHONE_IN_PAD );
1906 
1907  /* Hand off to network stack */
1908  netdev_rx ( netdev, iob_disown ( iobuf ) );
1909 
1910  profile_stop ( &iphone_in_profiler );
1911  return;
1912 
1913  error:
1914  netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
1915  ignore:
1916  free_iob ( iobuf );
1917 }
1918 
1919 /** Bulk IN endpoint operations */
1922 };
1923 
1924 /**
1925  * Transmit packet
1926  *
1927  * @v iphone iPhone device
1928  * @v iobuf I/O buffer
1929  * @ret rc Return status code
1930  */
1931 static int iphone_out_transmit ( struct iphone *iphone,
1932  struct io_buffer *iobuf ) {
1933  int rc;
1934 
1935  /* Profile transmissions */
1936  profile_start ( &iphone_out_profiler );
1937 
1938  /* Enqueue I/O buffer */
1939  if ( ( rc = usb_stream ( &iphone->usbnet.out, iobuf, 1 ) ) != 0 )
1940  return rc;
1941 
1942  profile_stop ( &iphone_out_profiler );
1943  return 0;
1944 }
1945 
1946 /**
1947  * Complete bulk OUT transfer
1948  *
1949  * @v ep USB endpoint
1950  * @v iobuf I/O buffer
1951  * @v rc Completion status code
1952  */
1953 static void iphone_out_complete ( struct usb_endpoint *ep,
1954  struct io_buffer *iobuf, int rc ) {
1955  struct iphone *iphone = container_of ( ep, struct iphone, usbnet.out );
1956  struct net_device *netdev = iphone->netdev;
1957 
1958  /* Report TX completion */
1959  netdev_tx_complete_err ( netdev, iobuf, rc );
1960 }
1961 
1962 /** Bulk OUT endpoint operations */
1965 };
1966 
1967 /**
1968  * Check pairing status
1969  *
1970  * @v iphone iPhone device
1971  * @ret rc Return status code
1972  */
1973 static int iphone_check_pair ( struct iphone *iphone ) {
1974  struct imux *imux;
1975 
1976  /* Find corresponding USB multiplexer */
1977  list_for_each_entry ( imux, &imuxes, list ) {
1978  if ( imux->usb == iphone->usb )
1979  return imux->rc;
1980  }
1981 
1982  return -EPIPE_NO_MUX;
1983 }
1984 
1985 /**
1986  * Check link status
1987  *
1988  * @v netdev Network device
1989  */
1990 static void iphone_check_link ( struct net_device *netdev ) {
1991  struct iphone *iphone = netdev->priv;
1992  struct usb_device *usb = iphone->usb;
1993  uint8_t status;
1994  int rc;
1995 
1996  /* Check pairing status */
1997  if ( ( rc = iphone_check_pair ( iphone ) ) != 0 )
1998  goto err_pair;
1999 
2000  /* Get link status */
2001  if ( ( rc = usb_control ( usb, IPHONE_GET_LINK, 0, 0, &status,
2002  sizeof ( status ) ) ) != 0 ) {
2003  DBGC ( iphone, "IPHONE %p could not get link status: %s\n",
2004  iphone, strerror ( rc ) );
2005  goto err_control;
2006  }
2007 
2008  /* Check link status */
2009  if ( status != IPHONE_LINK_UP ) {
2010  rc = -ENOTCONN_STATUS ( status );
2011  goto err_status;
2012  }
2013 
2014  /* Success */
2015  rc = 0;
2016 
2017  err_status:
2018  err_control:
2019  err_pair:
2020  /* Report link status. Since we have to check the link
2021  * periodically (due to an absence of an interrupt endpoint),
2022  * do this only if the link status has actually changed.
2023  */
2024  if ( rc != netdev->link_rc ) {
2025  if ( rc == 0 ) {
2026  DBGC ( iphone, "IPHONE %p link up\n", iphone );
2027  } else {
2028  DBGC ( iphone, "IPHONE %p link down: %s\n",
2029  iphone, strerror ( rc ) );
2030  }
2031  netdev_link_err ( netdev, rc );
2032  }
2033 }
2034 
2035 /**
2036  * Periodically update link status
2037  *
2038  * @v timer Link status timer
2039  * @v over Failure indicator
2040  */
2041 static void iphone_expired ( struct retry_timer *timer, int over __unused ) {
2042  struct iphone *iphone = container_of ( timer, struct iphone, timer );
2043  struct net_device *netdev = iphone->netdev;
2044 
2045  /* Check link status */
2047 
2048  /* Restart timer, if device is open */
2049  if ( netdev_is_open ( netdev ) )
2051 }
2052 
2053 /**
2054  * Open network device
2055  *
2056  * @v netdev Network device
2057  * @ret rc Return status code
2058  */
2059 static int iphone_open ( struct net_device *netdev ) {
2060  struct iphone *iphone = netdev->priv;
2061  int rc;
2062 
2063  /* Open USB network device */
2064  if ( ( rc = usbnet_open ( &iphone->usbnet ) ) != 0 ) {
2065  DBGC ( iphone, "IPHONE %p could not open: %s\n",
2066  iphone, strerror ( rc ) );
2067  goto err_open;
2068  }
2069 
2070  /* Start the link status check timer */
2072 
2073  return 0;
2074 
2075  usbnet_close ( &iphone->usbnet );
2076  err_open:
2077  return rc;
2078 }
2079 
2080 /**
2081  * Close network device
2082  *
2083  * @v netdev Network device
2084  */
2085 static void iphone_close ( struct net_device *netdev ) {
2086  struct iphone *iphone = netdev->priv;
2087 
2088  /* Stop the link status check timer */
2089  stop_timer ( &iphone->timer );
2090 
2091  /* Close USB network device */
2092  usbnet_close ( &iphone->usbnet );
2093 }
2094 
2095 /**
2096  * Transmit packet
2097  *
2098  * @v netdev Network device
2099  * @v iobuf I/O buffer
2100  * @ret rc Return status code
2101  */
2102 static int iphone_transmit ( struct net_device *netdev,
2103  struct io_buffer *iobuf ) {
2104  struct iphone *iphone = netdev->priv;
2105  int rc;
2106 
2107  /* Transmit packet */
2108  if ( ( rc = iphone_out_transmit ( iphone, iobuf ) ) != 0 )
2109  return rc;
2110 
2111  return 0;
2112 }
2113 
2114 /**
2115  * Poll for completed and received packets
2116  *
2117  * @v netdev Network device
2118  */
2119 static void iphone_poll ( struct net_device *netdev ) {
2120  struct iphone *iphone = netdev->priv;
2121  int rc;
2122 
2123  /* Poll USB bus */
2124  usb_poll ( iphone->bus );
2125 
2126  /* Refill endpoints */
2127  if ( ( rc = usbnet_refill ( &iphone->usbnet ) ) != 0 )
2128  netdev_rx_err ( netdev, NULL, rc );
2129 }
2130 
2131 /** iPhone network device operations */
2133  .open = iphone_open,
2134  .close = iphone_close,
2135  .transmit = iphone_transmit,
2136  .poll = iphone_poll,
2137 };
2138 
2139 /**
2140  * Probe device
2141  *
2142  * @v func USB function
2143  * @v config Configuration descriptor
2144  * @ret rc Return status code
2145  */
2146 static int iphone_probe ( struct usb_function *func,
2147  struct usb_configuration_descriptor *config ) {
2148  struct usb_device *usb = func->usb;
2149  struct net_device *netdev;
2150  struct iphone *iphone;
2151  int rc;
2152 
2153  /* Allocate and initialise structure */
2154  netdev = alloc_etherdev ( sizeof ( *iphone ) );
2155  if ( ! netdev ) {
2156  rc = -ENOMEM;
2157  goto err_alloc;
2158  }
2160  netdev->dev = &func->dev;
2161  iphone = netdev->priv;
2162  memset ( iphone, 0, sizeof ( *iphone ) );
2163  iphone->usb = usb;
2164  iphone->bus = usb->port->hub->bus;
2165  iphone->netdev = netdev;
2170  timer_init ( &iphone->timer, iphone_expired, &netdev->refcnt );
2171  DBGC ( iphone, "IPHONE %p on %s\n", iphone, func->name );
2172 
2173  /* Describe USB network device */
2174  if ( ( rc = usbnet_describe ( &iphone->usbnet, config ) ) != 0 ) {
2175  DBGC ( iphone, "IPHONE %p could not describe: %s\n",
2176  iphone, strerror ( rc ) );
2177  goto err_describe;
2178  }
2179 
2180  /* Fetch MAC address */
2181  if ( ( rc = usb_control ( usb, IPHONE_GET_MAC, 0, 0, netdev->hw_addr,
2182  ETH_ALEN ) ) != 0 ) {
2183  DBGC ( iphone, "IPHONE %p could not fetch MAC address: %s\n",
2184  iphone, strerror ( rc ) );
2185  goto err_fetch_mac;
2186  }
2187 
2188  /* Register network device */
2189  if ( ( rc = register_netdev ( netdev ) ) != 0 )
2190  goto err_register;
2191 
2192  /* Set initial link status */
2194 
2195  /* Add to list of iPhone network devices */
2196  list_add ( &iphone->list, &iphones );
2197 
2198  usb_func_set_drvdata ( func, iphone );
2199  return 0;
2200 
2201  list_del ( &iphone->list );
2203  err_register:
2204  err_fetch_mac:
2205  err_describe:
2206  netdev_nullify ( netdev );
2207  netdev_put ( netdev );
2208  err_alloc:
2209  return rc;
2210 }
2211 
2212 /**
2213  * Remove device
2214  *
2215  * @v func USB function
2216  */
2217 static void iphone_remove ( struct usb_function *func ) {
2218  struct iphone *iphone = usb_func_get_drvdata ( func );
2219  struct net_device *netdev = iphone->netdev;
2220 
2221  list_del ( &iphone->list );
2223  netdev_nullify ( netdev );
2224  netdev_put ( netdev );
2225 }
2226 
2227 /** iPhone device IDs */
2228 static struct usb_device_id iphone_ids[] = {
2229  {
2230  .name = "iphone",
2231  .vendor = 0x05ac,
2232  .product = USB_ANY_ID,
2233  },
2234 };
2235 
2236 /** iPhone driver */
2237 struct usb_driver iphone_driver __usb_driver = {
2238  .ids = iphone_ids,
2239  .id_count = ( sizeof ( iphone_ids ) / sizeof ( iphone_ids[0] ) ),
2240  .class = USB_CLASS_ID ( 0xff, 0xfd, 0x01 ),
2241  .score = USB_SCORE_NORMAL,
2242  .probe = iphone_probe,
2243  .remove = iphone_remove,
2244 };
2245 
2246 /* Drag in objects via iphone_driver */
2247 REQUIRING_SYMBOL ( iphone_driver );
2248 
2249 /* Drag in RSA-with-SHA256 OID prefixes */
2250 REQUIRE_OBJECT ( rsa_sha256 );
Transport Layer Security Protocol.
static void ipair_close(struct ipair *ipair, int rc)
Shut down pairing client.
Definition: iphone.c:1246
A process.
Definition: process.h:18
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
A USB driver.
Definition: usb.h:1407
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:1384
#define __attribute__(x)
Definition: compiler.h:10
iPhone USB Ethernet driver
#define EINVAL
Invalid argument.
Definition: errno.h:429
An object interface operation.
Definition: interface.h:18
uint32_t tcp_ack
Pseudo-TCP acknowledgement number.
Definition: iphone.h:143
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void imux_rx_log(struct imux *imux, struct imux_header *hdr, size_t len)
Receive log message.
Definition: iphone.c:759
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:224
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:147
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
A USB device ID.
Definition: usb.h:1361
static void privkey_put(struct private_key *key)
Drop reference to private key.
Definition: privkey.h:42
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
void * data
Data.
Definition: asn1.h:36
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
#define iob_put(iobuf, len)
Definition: iobuf.h:125
#define va_end(ap)
Definition: stdarg.h:10
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:496
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:587
Data transfer metadata.
Definition: xfer.h:23
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
#define SHA256_DIGEST_SIZE
Definition: Tpm20.h:30
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:465
static int imux_tx_syn(struct imux *imux)
Transmit pseudo-TCP SYN.
Definition: iphone.c:694
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:256
static const char icert_end[]
PEM certificate suffix.
Definition: iphone.c:324
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:62
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:718
static LIST_HEAD(imuxes)
List of USB multiplexers.
#define ASN1_SHORT(tag,...)
Construct a short ASN.1 value.
Definition: asn1.h:105
#define icert_public
Definition: iphone.c:317
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:100
int(* tx)(struct ipair *ipair)
Transmit message.
Definition: iphone.h:196
static int iphone_check_pair(struct iphone *iphone)
Check pairing status.
Definition: iphone.c:1973
const char * name
Name.
Definition: usb.h:676
An iPhone USB multiplexed packet header.
Definition: iphone.h:50
static void iphone_check_link(struct net_device *netdev)
Check link status.
Definition: iphone.c:1990
#define IMUX_IN_MAX_FILL
Multiplexer bulk IN maximum fill level.
Definition: iphone.h:159
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:223
struct stp_switch root
Root switch.
Definition: stp.h:27
const char * name
Name.
Definition: usb.h:1363
static struct asn1_cursor icert_name_ipxe
"iPXE" subject name
Definition: iphone.c:221
#define IPHONE_IN_PAD
Bulk IN padding.
Definition: iphone.h:272
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
static void imux_rx_syn(struct imux *imux)
Receive pseudo-TCP SYN+ACK.
Definition: iphone.c:794
#define SHA256_CTX_SIZE
SHA-256 context size.
Definition: sha256.h:72
struct refcnt refcnt
Reference count.
Definition: x509.h:377
#define ASN1_BOOLEAN
ASN.1 boolean.
Definition: asn1.h:60
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
static int ipair_create(struct interface *xfer, unsigned int flags)
Create a pairing client.
Definition: iphone.c:1835
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
static struct interface_operation ipair_xfer_operations[]
Pairing client interface operations.
Definition: iphone.c:1818
static int ipair_tx(struct ipair *ipair, const char *fmt,...)
Transmit XML message.
Definition: iphone.c:1264
#define TCP_ACK
Definition: tcp.h:160
#define iob_push(iobuf, len)
Definition: iobuf.h:89
static void ipair_expired(struct retry_timer *timer, int over __unused)
Pairing transmission timer.
Definition: iphone.c:1800
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
static struct asn1_cursor icert_leaf_exts
Extensions used in constructed leaf certificates.
Definition: iphone.c:171
static void imux_rx_version(struct imux *imux)
Receive version message.
Definition: iphone.c:743
FILE_SECBOOT(PERMITTED)
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:230
static const uint8_t icert_public_a [] __unused
Public key(s) used for pairing.
Definition: iphone.c:238
uint32_t type
Operating system type.
Definition: ena.h:12
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:37
int(* action)(struct imux *imux)
Pending action.
Definition: iphone.h:134
#define EPIPE
Broken pipe.
Definition: errno.h:620
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
struct arbelprm_completion_with_error error
Definition: arbel.h:12
TCP packet.
Definition: iphone.h:70
struct interface tcp
Pseudo-TCP lockdown socket interface.
Definition: iphone.h:148
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
static int ipair_rx_pair(struct ipair *ipair, char *msg)
Receive Pair message.
Definition: iphone.c:1607
char msg[0]
Message.
Definition: iphone.h:88
uint16_t out_seq
Output sequence.
Definition: iphone.h:139
static struct x509_root icert_root
Root of trust for iPhone certificates.
Definition: iphone.c:95
const void * data
Start of data.
Definition: asn1.h:23
#define DBGC(...)
Definition: compiler.h:505
struct interface xfer
Data transfer interface.
Definition: iphone.h:187
uint8_t flags
Definition: tcp.h:26
A process descriptor.
Definition: process.h:32
uint32_t seq
Definition: tcp.h:23
A retry timer.
Definition: retry.h:22
#define ENOENT
No such file or directory.
Definition: errno.h:515
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition: usb.c:546
An iPhone USB multiplexed pseudo-TCP message header.
Definition: iphone.h:92
#define ntohl(value)
Definition: byteswap.h:135
static const uint8_t icert_root_exts_data[]
Extensions used in constructed root certificate.
Definition: iphone.c:121
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:159
#define IMUX_WINDOW
Advertised TCP window.
Definition: iphone.h:112
static const char ipair_prefix[]
Common prefix for all pairing messages.
Definition: iphone.c:1200
uint32_t protocol
Protocol.
Definition: iphone.h:52
#define ntohs(value)
Definition: byteswap.h:137
An iPhone USB multiplexed log message header.
Definition: iphone.h:82
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition: base64.c:92
static struct usb_endpoint_driver_operations imux_out_operations
Bulk OUT endpoint operations.
Definition: iphone.c:946
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition: x509.c:1313
static const char ipair_host_id[]
Arbitrary host ID used for pairing.
Definition: iphone.c:1219
struct x509_certificate * device
Device certificate.
Definition: iphone.h:39
static int ipair_rx_session_error(struct ipair *ipair, char *error)
Receive StartSession message error.
Definition: iphone.c:1670
A data structure for storing profiling information.
Definition: profile.h:27
#define TCP_RST
Definition: tcp.h:162
uint16_t device
Device ID.
Definition: ena.h:24
static int ipair_rx_session(struct ipair *ipair, char *msg)
Receive StartSession message.
Definition: iphone.c:1694
int open
Endpoint is open.
Definition: usb.h:419
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:174
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:80
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:131
#define htonl(value)
Definition: byteswap.h:134
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
#define ASN1_SET
ASN.1 set.
Definition: asn1.h:93
static void imux_rx_tcp(struct imux *imux, struct io_buffer *iobuf)
Receive pseudo-TCP message.
Definition: iphone.c:809
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
#define IMUX_PORT_LOCAL
Local port number.
Definition: iphone.h:103
static int ipair_rx(struct ipair *ipair, char *msg, size_t len)
Receive XML message payload.
Definition: iphone.c:1308
static int icert_certs(struct icert *icert, struct asn1_cursor *key)
Construct certificates.
Definition: iphone.c:448
#define ECANCELED
Operation canceled.
Definition: errno.h:344
static void iphone_remove(struct usb_function *func)
Remove device.
Definition: iphone.c:2217
Log message.
Definition: iphone.h:68
static const char icert_begin[]
PEM certificate prefix.
Definition: iphone.c:321
#define TCP_SYN
Definition: tcp.h:163
Data transfer interfaces.
size_t len
Length of data.
Definition: asn1.h:25
An iPhone pairing client.
Definition: iphone.h:183
A reference counter.
Definition: refcnt.h:27
A timer.
Definition: timer.h:29
static const uint8_t icert_sha256_rsa[]
"SHA-256 with RSA algorithm" identifier used in constructed certificates
Definition: iphone.c:114
#define IPHONE_IN_MTU
Bulk IN buffer size.
Definition: iphone.h:278
uint32_t start
Starting offset.
Definition: netvsc.h:12
static struct net_device_operations iphone_operations
iPhone network device operations
Definition: iphone.c:2132
static const uint8_t icert_name_ipxe_data[]
"iPXE" subject name
Definition: iphone.c:213
unsigned long tmp
Definition: linux_pci.h:65
static struct asn1_cursor icert_name_iphone
"iPhone" subject name
Definition: iphone.c:234
static struct interface_descriptor imux_tcp_desc
Pseudo-TCP socket interface descriptor.
Definition: iphone.c:1061
struct usb_endpoint out
Bulk OUT endpoint.
Definition: usbnet.h:32
static void iphone_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition: iphone.c:2119
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:519
struct x509_certificate * host
Host certificate.
Definition: iphone.h:37
#define DBGCP_HDA(...)
Definition: compiler.h:540
struct asn1_builder builder
ASN.1 object builder.
Definition: privkey.h:21
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
char * strstr(const char *haystack, const char *needle)
Find substring.
Definition: string.c:310
static size_t base64_encoded_len(size_t raw_len)
Calculate length of base64-encoded data.
Definition: base64.h:22
#define ENOMEM
Not enough space.
Definition: errno.h:535
A hardware device.
Definition: device.h:77
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
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
static size_t base64_decoded_max_len(const char *encoded)
Calculate maximum length of base64-decoded string.
Definition: base64.h:35
A USB endpoint.
Definition: usb.h:404
static int iphone_open(struct net_device *netdev)
Open network device.
Definition: iphone.c:2059
struct refcnt refcnt
Reference counter.
Definition: iphone.h:185
Standalone length has been received.
Definition: iphone.h:216
static struct asn1_cursor icert_root_exts
Extensions used in constructed root certificate.
Definition: iphone.c:138
const char * name
Name.
Definition: profile.h:29
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 netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:662
#define EPIPE_NO_MUX
Definition: iphone.c:52
#define ASN1_OID_BASICCONSTRAINTS
ASN.1 OID for id-ce-basicConstraints (2.5.29.19)
Definition: asn1.h:332
#define EINPROGRESS_PAIRING
Definition: iphone.c:56
static struct asn1_cursor icert_name_root
"Root" subject name
Definition: iphone.c:209
uint32_t ack
Definition: tcp.h:24
struct usb_port * port
USB port.
Definition: usb.h:727
int link_rc
Link status code.
Definition: netdevice.h:402
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
static int imux_tx_version(struct imux *imux)
Transmit version message.
Definition: iphone.c:634
static const uint8_t icert_name_root_data[]
"Root" subject name
Definition: iphone.c:201
Ethernet protocol.
An object interface.
Definition: interface.h:125
struct tcp_header tcp
Pseudo-TCP header.
Definition: iphone.h:96
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition: asn1.h:402
static uint8_t icert_root_fingerprint[SHA256_DIGEST_SIZE]
iPhone root certificate fingerprint
Definition: iphone.c:92
static int ipair_deliver(struct ipair *ipair, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle received data.
Definition: iphone.c:1763
void * priv
Driver private data.
Definition: netdevice.h:432
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
#define DBGC_HDA(...)
Definition: compiler.h:506
PEM-encoded ASN.1 data.
ring len
Length.
Definition: dwmac.h:231
struct digest_algorithm * digest
Fingerprint digest algorithm.
Definition: x509.h:379
uint16_t win
Definition: tcp.h:27
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
static int icert_encode(struct icert *icert, struct x509_certificate *cert, char **encenc)
Construct doubly base64-encoded certificate.
Definition: iphone.c:531
static struct net_device * netdev
Definition: gdbudp.c:52
struct usb_driver imux_driver __usb_driver
USB multiplexer driver.
Definition: iphone.c:1183
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:347
static const uint8_t icert_name_iphone_data[]
"iPhone" subject name
Definition: iphone.c:225
#define ENOTCONN_STATUS(status)
Definition: iphone.c:64
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:707
An iPhone USB multiplexed version message header.
Definition: iphone.h:74
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:161
Profiling.
#define ASN1_OID_COMMON_NAME
ASN.1 OID for commonName (2.5.4.3)
Definition: asn1.h:322
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:942
uint16_t dest
Definition: tcp.h:22
static const uint8_t icert_validity[]
Validity period in constructed certificates.
Definition: iphone.c:187
#define ASN1_NULL
ASN.1 null.
Definition: asn1.h:72
static int imux_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: iphone.c:1104
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition: usbnet.c:152
#define ASN1_GENERALIZED_TIME
ASN.1 generalized time.
Definition: asn1.h:87
A USB device.
Definition: usb.h:723
#define EPROTO
Protocol error.
Definition: errno.h:625
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
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 struct interface_descriptor ipair_xfer_desc
Pairing client interface descriptor.
Definition: iphone.c:1825
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:219
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition: usb.h:1072
An object interface descriptor.
Definition: interface.h:56
Request a new pairing.
Definition: iphone.h:214
static const char ipair_system_buid[]
Arbitrary system BUID used for pairing.
Definition: iphone.c:1216
uint8_t flags
Flags.
Definition: ena.h:18
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An X.509 certificate.
Definition: x509.h:216
struct refcnt refcnt
Reference counter.
Definition: netdevice.h:355
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
static void iphone_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition: iphone.c:1879
static int iphone_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: iphone.c:2102
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:760
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
static struct profiler iphone_in_profiler __profiler
Bulk IN completion profiler.
Definition: iphone.c:71
An ASN.1 object builder.
Definition: asn1.h:29
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1389
A network device.
Definition: netdevice.h:353
void netdev_link_err(struct net_device *netdev, int rc)
Mark network device as having a specific link state.
Definition: netdevice.c:208
struct usb_endpoint in
Bulk IN endpoint.
Definition: usbnet.h:30
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
REQUIRE_OBJECT(rsa_sha256)
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:532
Normal driver.
Definition: usb.h:1453
struct usb_device * usb
USB device.
Definition: iphone.h:257
unsigned char uint8_t
Definition: stdint.h:10
static struct usb_endpoint_driver_operations iphone_out_operations
Bulk OUT endpoint operations.
Definition: iphone.c:1963
struct usb_bus * bus
USB bus.
Definition: iphone.h:121
uint16_t in_seq
Input sequence.
Definition: iphone.h:137
static int iphone_out_transmit(struct iphone *iphone, struct io_buffer *iobuf)
Transmit packet.
Definition: iphone.c:1931
X.509 certificates.
#define ETH_ALEN
Definition: if_ether.h:9
static void imux_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition: iphone.c:930
An iPhone USB multiplexer.
Definition: iphone.h:115
struct usb_device * usb
USB device.
Definition: usb.h:678
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition: asn1.c:999
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:90
static const uint8_t icert_rsa[]
"RSA algorithm" identifier used in constructed certificates
Definition: iphone.c:106
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
static struct usb_endpoint_driver_operations iphone_in_operations
Bulk IN endpoint operations.
Definition: iphone.c:1920
void * memmove(void *dest, const void *src, size_t len) __nonnull
void x509_fingerprint(struct x509_certificate *cert, struct digest_algorithm *digest, void *fingerprint)
Calculate X.509 certificate fingerprint.
Definition: x509.c:1237
struct usbnet_device usbnet
USB network device.
Definition: iphone.h:123
static int ipair_tx_pubkey(struct ipair *ipair)
Transmit DevicePublicKey message.
Definition: iphone.c:1412
#define ASN1_UTF8_STRING
ASN.1 UTF-8 string.
Definition: asn1.h:81
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:63
struct x509_certificate * root
Root certificate.
Definition: iphone.h:35
static int process_running(struct process *process)
Check if process is running.
Definition: process.h:176
uint8_t status
Status.
Definition: ena.h:16
Network device operations.
Definition: netdevice.h:214
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:549
struct device * dev
Underlying hardware device.
Definition: netdevice.h:365
static int imux_tx_tcp(struct imux *imux, struct io_buffer *iobuf)
Transmit pseudo-TCP message.
Definition: iphone.c:663
#define EPERM
Operation not permitted.
Definition: errno.h:615
struct usb_device * usb
USB device.
Definition: iphone.h:119
static const char ipair_suffix[]
Common suffix for all pairing messages.
Definition: iphone.c:1211
Base64 encoding.
Network device management.
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
static void iphone_expired(struct retry_timer *timer, int over __unused)
Periodically update link status.
Definition: iphone.c:2041
An X.509 root certificate list.
Definition: x509.h:375
#define IPAIR_RETRY_DELAY
Pairing retry delay.
Definition: iphone.h:225
struct icert icert
Pairing certificates.
Definition: iphone.h:208
RSA public-key cryptography.
#define iob_reserve(iobuf, len)
Definition: iobuf.h:72
static int ipair_tag(struct ipair *ipair, const char *msg, const char *tag, char **start, char **end)
Locate XML tag.
Definition: iphone.c:1350
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
static void imux_close(struct imux *imux, int rc)
Close USB multiplexer.
Definition: iphone.c:973
A USB configuration descriptor.
Definition: usb.h:210
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:147
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:75
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118
uint32_t tcp_seq
Pseudo-TCP sequence number.
Definition: iphone.h:141
struct digest_algorithm sha256_algorithm
SHA-256 algorithm.
Definition: sha256.c:265
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition: netdevice.c:471
Version number.
Definition: iphone.h:66
#define IMUX_PORT_LOCKDOWND
Lockdown daemon port number.
Definition: iphone.h:106
struct process process
Polling process.
Definition: iphone.h:128
unsigned int flags
Pairing flags.
Definition: iphone.h:150
static int ipair_tx_session(struct ipair *ipair)
Transmit StartSession message.
Definition: iphone.c:1643
uint8_t level
Log level.
Definition: iphone.h:86
static void imux_remove(struct usb_function *func)
Remove device.
Definition: iphone.c:1165
An iPhone network device.
Definition: iphone.h:255
#define DBGC2(...)
Definition: compiler.h:522
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1373
__builtin_va_list va_list
Definition: stdarg.h:7
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:174
Universal Serial Bus (USB)
size_t digestsize
Digest size.
Definition: crypto.h:27
static int ipair_rx_pubkey(struct ipair *ipair, char *msg)
Receive DevicePublicKey message.
Definition: iphone.c:1435
static void ipair_free(struct refcnt *refcnt)
Free pairing client.
Definition: iphone.c:1233
#define IMUX_IN_MTU
Multiplexer bulk IN buffer size.
Definition: iphone.h:165
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
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:278
void * data
Start of data.
Definition: iobuf.h:53
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:83
static int imux_tx(struct imux *imux, struct io_buffer *iobuf)
Transmit message.
Definition: iphone.c:601
static struct usb_device_id imux_ids[]
USB multiplexer device IDs.
Definition: iphone.c:1174
struct usb_hub * hub
USB hub.
Definition: usb.h:815
static int ipair_tx_pair(struct ipair *ipair)
Transmit Pair message.
Definition: iphone.c:1518
struct private_key * key
"Private" key
Definition: iphone.h:33
#define IPHONE_IN_MAX_FILL
Bulk IN maximum fill level.
Definition: iphone.h:284
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
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:265
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition: wpa.h:234
struct pubkey_algorithm rsa_algorithm
RSA public-key algorithm.
Definition: rsa.c:661
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ASN1_OID_RSAENCRYPTION
ASN.1 OID for rsaEncryption (1.2.840.113549.1.1.1)
Definition: asn1.h:168
A message digest algorithm.
Definition: crypto.h:19
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
uint32_t end
Ending offset.
Definition: netvsc.h:18
uint16_t port
Pseudo-TCP local port number.
Definition: iphone.h:145
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int(* rx)(struct ipair *ipair, char *msg)
Receive message.
Definition: iphone.h:203
struct refcnt refcnt
Reference counter.
Definition: iphone.h:117
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:78
static void imux_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition: iphone.c:867
struct retry_timer timer
Link status check timer.
Definition: iphone.h:268
int ssize_t const char * fmt
Definition: vsprintf.h:73
#define DBGCP(...)
Definition: compiler.h:539
uint16_t src
Definition: tcp.h:21
__be32 raw[7]
Definition: CIB_PRM.h:28
#define IPHONE_LINK_CHECK_INTERVAL
Link check interval.
Definition: iphone.h:290
REQUIRING_SYMBOL(iphone_driver)
static struct asn1_cursor * asn1_built(struct asn1_builder *builder)
Get cursor for built object.
Definition: asn1.h:492
struct imux_header hdr
Multiplexed packet header.
Definition: iphone.h:76
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition: usbnet.c:278
static void privkey_init(struct private_key *key)
Initialise empty private key.
Definition: privkey.h:64
#define IPHONE_GET_MAC
Get MAC address.
Definition: iphone.h:235
static struct process_descriptor imux_process_desc
Multiplexer process descriptor.
Definition: iphone.c:1094
static const uint8_t icert_leaf_exts_data[]
Extensions used in constructed leaf certificates.
Definition: iphone.c:142
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:99
static void imux_shutdown(struct imux *imux)
Shut down USB multiplexer.
Definition: iphone.c:955
uint8_t meta
Metadata flags.
Definition: ena.h:14
An iPhone USB multiplexed pseudo-TCP XML message header.
Definition: iphone.h:175
#define va_start(ap, last)
Definition: stdarg.h:8
static struct usb_endpoint_driver_operations imux_in_operations
Bulk IN endpoint operations.
Definition: iphone.c:919
static int ipair_rx_pair_error(struct ipair *ipair, char *error)
Receive Pair message error.
Definition: iphone.c:1583
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:231
struct usbnet_device usbnet
USB network device.
Definition: iphone.h:263
void usbnet_close(struct usbnet_device *usbnet)
Close USB network device.
Definition: usbnet.c:128
int rc
Pairing status.
Definition: iphone.h:152
USB endpoint driver operations.
Definition: usb.h:489
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
struct device dev
Generic device.
Definition: usb.h:682
A USB function.
Definition: usb.h:674
static void iphone_close(struct net_device *netdev)
Close network device.
Definition: iphone.c:2085
struct usb_bus * bus
USB bus.
Definition: usb.h:845
#define IPHONE_GET_LINK
Get link status.
Definition: iphone.h:240
uint64_t tag
Identity tag.
Definition: edd.h:31
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:69
int const char * format
Definition: xfer.h:105
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
SHA-256 algorithm.
Link up.
Definition: iphone.h:249
static int iphone_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: iphone.c:2146
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition: refcnt.c:102
TLS session has been started.
Definition: iphone.h:218
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:382
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
size_t len
Length of data.
Definition: asn1.h:38
static void imux_step(struct imux *imux)
Multiplexer process.
Definition: iphone.c:1069
String functions.
unsigned int flags
State flags.
Definition: iphone.h:205
An ASN.1 object cursor.
Definition: asn1.h:21
A public key algorithm.
Definition: crypto.h:122
#define htons(value)
Definition: byteswap.h:136
static const uint8_t icert_tbs_prefix[]
"TBSCertificate" prefix in constructed certificates
Definition: iphone.c:175
static void ipair_window_changed(struct ipair *ipair)
Handle window change notification.
Definition: iphone.c:1736
static struct usb_device_id iphone_ids[]
iPhone device IDs
Definition: iphone.c:2228
struct usb_bus * bus
USB bus.
Definition: iphone.h:259
#define ASN1_BIT_STRING
ASN.1 bit string.
Definition: asn1.h:66
struct net_device * netdev
Network device.
Definition: iphone.h:261
union @391 key
Sense key.
Definition: scsi.h:18
An iPhone pairing certificate set.
Definition: iphone.h:31
static void icert_free(struct icert *icert)
Free pairing certificates.
Definition: iphone.c:331
struct retry_timer timer
Pairing timer.
Definition: iphone.h:190
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
static int imux_start_pair(struct imux *imux)
Open pairing client.
Definition: iphone.c:725
uint8_t hlen
Definition: tcp.h:25
size_t base64_encode(const void *raw, size_t raw_len, char *data, size_t len)
Base64-encode data.
Definition: base64.c:52
static const uint8_t icert_nul[]
Single zero byte used in constructed certificates.
Definition: iphone.c:103
#define ASN1_OID_KEYUSAGE
ASN.1 OID for id-ce-keyUsage (2.5.29.15)
Definition: asn1.h:327
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
struct list_head list
List of USB multiplexers.
Definition: iphone.h:125
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1409
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition: wpa.h:237
#define icert_private
Definition: iphone.c:318
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
Write a formatted string to a buffer.
Definition: vsprintf.c:352
struct list_head list
List of iPhone network devices.
Definition: iphone.h:266
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:38
static struct interface_operation imux_tcp_operations[]
Pseudo-TCP socket interface operations.
Definition: iphone.c:1054
static void iphone_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition: iphone.c:1953
#define ASN1_OID_SHA256WITHRSAENCRYPTION
ASN.1 OID for sha256WithRSAEncryption (1.2.840.113549.1.1.11)
Definition: asn1.h:186
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition: usbnet.c:55