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