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 len;
366  int rc;
367 
368  /* Construct subjectPublicKeyInfo */
369  if ( ( rc = ( asn1_prepend_raw ( &spki, public->data, public->len ),
370  asn1_prepend_raw ( &spki, icert_nul,
371  sizeof ( icert_nul ) ),
372  asn1_wrap ( &spki, ASN1_BIT_STRING ),
373  asn1_prepend_raw ( &spki, icert_rsa,
374  sizeof ( icert_rsa ) ),
375  asn1_wrap ( &spki, ASN1_SEQUENCE ) ) ) != 0 ) {
376  DBGC ( icert, "ICERT %p could not build subjectPublicKeyInfo: "
377  "%s\n", icert, strerror ( rc ) );
378  goto err_spki;
379  }
380 
381  /* Construct tbsCertificate */
382  if ( ( rc = ( asn1_prepend_raw ( &tbs, exts->data, exts->len ),
383  asn1_prepend_raw ( &tbs, spki.data, spki.len ),
384  asn1_prepend_raw ( &tbs, subject->data, subject->len ),
386  sizeof ( icert_validity ) ),
387  asn1_prepend_raw ( &tbs, issuer->data, issuer->len ),
389  sizeof ( icert_tbs_prefix ) ),
390  asn1_wrap ( &tbs, ASN1_SEQUENCE ) ) ) != 0 ) {
391  DBGC ( icert, "ICERT %p could not build tbsCertificate: %s\n",
392  icert, strerror ( rc ) );
393  goto err_tbs;
394  }
395 
396  /* Calculate certificate digest */
397  digest_init ( digest, digest_ctx );
398  digest_update ( digest, digest_ctx, tbs.data, tbs.len );
399  digest_final ( digest, digest_ctx, digest_out );
400 
401  /* Construct signature using "private" key */
402  if ( ( rc = asn1_grow ( &raw,
403  pubkey_max_len ( pubkey, private ) ) ) != 0 ) {
404  DBGC ( icert, "ICERT %p could not build signature: %s\n",
405  icert, strerror ( rc ) );
406  goto err_grow;
407  }
408  if ( ( len = pubkey_sign ( pubkey, private, digest, digest_out,
409  raw.data ) ) < 0 ) {
410  rc = len;
411  DBGC ( icert, "ICERT %p could not sign: %s\n",
412  icert, strerror ( rc ) );
413  goto err_pubkey_sign;
414  }
415  assert ( ( ( size_t ) len ) == raw.len );
416 
417  /* Construct raw certificate data */
418  if ( ( rc = ( asn1_prepend_raw ( &raw, icert_nul,
419  sizeof ( icert_nul ) ),
422  sizeof ( icert_sha256_rsa ) ),
423  asn1_prepend_raw ( &raw, tbs.data, tbs.len ),
424  asn1_wrap ( &raw, ASN1_SEQUENCE ) ) ) != 0 ) {
425  DBGC ( icert, "ICERT %p could not build certificate: %s\n",
426  icert, strerror ( rc ) );
427  goto err_raw;
428  }
429 
430  /* Parse certificate */
431  if ( ( rc = x509_certificate ( raw.data, raw.len, cert ) ) != 0 ) {
432  DBGC ( icert, "ICERT %p invalid certificate: %s\n",
433  icert, strerror ( rc ) );
434  DBGC_HDA ( icert, 0, raw.data, raw.len );
435  goto err_x509;
436  }
437 
438  err_x509:
439  err_raw:
440  err_pubkey_sign:
441  free ( raw.data );
442  err_grow:
443  free ( tbs.data );
444  err_tbs:
445  free ( spki.data );
446  err_spki:
447  return rc;
448 }
449 
450 /**
451  * Construct certificates
452  *
453  * @v icert Certificate set
454  * @v pubkey Device public key
455  * @ret rc Return status code
456  */
457 static int icert_certs ( struct icert *icert, struct asn1_cursor *key ) {
458  struct digest_algorithm *digest = icert_root.digest;
459  struct asn1_builder public = { NULL, 0 };
460  struct asn1_builder *private;
461  int rc;
462 
463  /* Free any existing key and certificates */
464  icert_free ( icert );
465 
466  /* Allocate "private" key */
467  icert->key = zalloc ( sizeof ( *icert->key ) );
468  if ( ! icert->key ) {
469  rc = -ENOMEM;
470  goto error;
471  }
472  privkey_init ( icert->key );
473  private = &icert->key->builder;
474 
475  /* Construct our "private" key */
476  if ( ( rc = ( asn1_prepend_raw ( private, icert_private,
477  sizeof ( icert_private ) ),
478  asn1_prepend_raw ( private, icert_public,
479  sizeof ( icert_public ) ),
480  asn1_prepend ( private, ASN1_INTEGER, icert_nul,
481  sizeof ( icert_nul ) ),
482  asn1_wrap ( private, ASN1_SEQUENCE ) ) ) != 0 ) {
483  DBGC ( icert, "ICERT %p could not build private key: %s\n",
484  icert, strerror ( rc ) );
485  goto error;
486  }
487 
488  /* Construct our own public key */
489  if ( ( rc = ( asn1_prepend_raw ( &public, icert_public,
490  sizeof ( icert_public ) ),
491  asn1_wrap ( &public, ASN1_SEQUENCE ) ) ) != 0 ) {
492  DBGC ( icert, "ICERT %p could not build public key: %s\n",
493  icert, strerror ( rc ) );
494  goto error;
495  }
496 
497  /* Construct root certificate */
499  asn1_built ( private ), asn1_built ( &public ),
500  &icert_root_exts, &icert->root ) ) != 0 )
501  goto error;
502 
503  /* Construct host certificate */
505  asn1_built ( private ), asn1_built ( &public ),
506  &icert_leaf_exts, &icert->host ) ) != 0 )
507  goto error;
508 
509  /* Construct device certificate */
511  asn1_built ( private ), key,
512  &icert_leaf_exts, &icert->device ) ) != 0 )
513  goto error;
514 
515  /* Construct root of trust */
516  assert ( digest->digestsize == sizeof ( icert_root_fingerprint ) );
518 
519  /* Free constructed keys */
520  free ( public.data );
521  return 0;
522 
523  error:
524  icert_free ( icert );
525  free ( public.data );
526  return rc;
527 }
528 
529 /**
530  * Construct doubly base64-encoded certificate
531  *
532  * @v icert Pairing certificates
533  * @v cert X.509 certificate
534  * @v encenc Doubly base64-encoded certificate to construct
535  * @ret rc Return status code
536  *
537  * On success, the caller is responsible for eventually calling free()
538  * on the allocated doubly encoded encoded certificate.
539  */
540 static int icert_encode ( struct icert *icert, struct x509_certificate *cert,
541  char **encenc ) {
542  size_t encencoded_len;
543  size_t encoded_len;
544  size_t pem_len;
545  char *pem;
546  int rc;
547 
548  /* Sanity check */
549  assert ( cert != NULL );
550 
551  /* Create PEM */
552  encoded_len = ( base64_encoded_len ( cert->raw.len ) + 1 /* NUL */ );
553  pem_len = ( ( sizeof ( icert_begin ) - 1 /* NUL */ ) +
554  ( encoded_len - 1 /* NUL */ ) +
555  ( sizeof ( icert_end ) - 1 /* NUL */ ) +
556  1 /* NUL */ );
557  pem = malloc ( pem_len );
558  if ( ! pem ) {
559  rc = -ENOMEM;
560  goto err_alloc_pem;
561  }
562  strcpy ( pem, icert_begin );
563  base64_encode ( cert->raw.data, cert->raw.len,
564  ( pem + sizeof ( icert_begin ) - 1 /* NUL */ ),
565  encoded_len );
566  strcpy ( ( pem +
567  ( sizeof ( icert_begin ) - 1 /* NUL */ ) +
568  ( encoded_len - 1 /* NUL */ ) ), icert_end );
569  DBGC2 ( icert, "ICERT %p \"%s\" certificate:\n%s",
570  icert, x509_name ( cert ), pem );
571 
572  /* Base64-encode the PEM (sic) */
573  encencoded_len = ( base64_encoded_len ( pem_len - 1 /* NUL */ )
574  + 1 /* NUL */ );
575  *encenc = malloc ( encencoded_len );
576  if ( ! *encenc ) {
577  rc = -ENOMEM;
578  goto err_alloc_encenc;
579  }
580  base64_encode ( pem, ( pem_len - 1 /* NUL */ ), *encenc,
581  encencoded_len );
582 
583  /* Success */
584  rc = 0;
585 
586  err_alloc_encenc:
587  free ( pem );
588  err_alloc_pem:
589  return rc;
590 }
591 
592 /******************************************************************************
593  *
594  * iPhone USB multiplexer
595  *
596  ******************************************************************************
597  *
598  * The iPhone USB multiplexer speaks a protocol that is almost, but
599  * not quite, entirely unlike TCP.
600  *
601  */
602 
603 /**
604  * Transmit message
605  *
606  * @v imux USB multiplexer
607  * @v iobuf I/O buffer
608  * @ret rc Return status code
609  */
610 static int imux_tx ( struct imux *imux, struct io_buffer *iobuf ) {
611  struct imux_header *hdr = iobuf->data;
612  size_t len = iob_len ( iobuf );
613  int rc;
614 
615  /* Populate header */
616  assert ( len >= sizeof ( *hdr ) );
617  hdr->len = htonl ( len );
618  hdr->in_seq = htons ( imux->in_seq );
619  hdr->out_seq = htons ( imux->out_seq );
620  DBGCP ( imux, "IMUX %p transmitting:\n", imux );
621  DBGCP_HDA ( imux, 0, hdr, len );
622 
623  /* Transmit message */
624  if ( ( rc = usb_stream ( &imux->usbnet.out, iobuf, 1 ) ) != 0 )
625  goto err;
626 
627  /* Increment sequence number */
628  imux->out_seq++;
629 
630  return 0;
631 
632  err:
633  free_iob ( iobuf );
634  return rc;
635 }
636 
637 /**
638  * Transmit version message
639  *
640  * @v imux USB multiplexer
641  * @ret rc Return status code
642  */
643 static int imux_tx_version ( struct imux *imux ) {
644  struct io_buffer *iobuf;
645  struct imux_header_version *vers;
646  int rc;
647 
648  /* Allocate I/O buffer */
649  iobuf = alloc_iob ( sizeof ( *vers ) );
650  if ( ! iobuf )
651  return -ENOMEM;
652  vers = iob_put ( iobuf, sizeof ( *vers ) );
653 
654  /* Construct version message */
655  memset ( vers, 0, sizeof ( *vers ) );
656  vers->hdr.protocol = htonl ( IMUX_VERSION );
657 
658  /* Transmit message */
659  if ( ( rc = imux_tx ( imux, iob_disown ( iobuf ) ) ) != 0 )
660  return rc;
661 
662  return 0;
663 }
664 
665 /**
666  * Transmit pseudo-TCP message
667  *
668  * @v imux USB multiplexer
669  * @v iobuf I/O buffer
670  * @ret rc Return status code
671  */
672 static int imux_tx_tcp ( struct imux *imux, struct io_buffer *iobuf ) {
673  struct imux_header_tcp *tcp = iobuf->data;
674  size_t len = iob_len ( iobuf );
675  int rc;
676 
677  /* Populate TCP header */
678  assert ( len >= sizeof ( *tcp ) );
679  tcp->hdr.protocol = htonl ( IMUX_TCP );
680  tcp->tcp.src = htons ( imux->port );
681  tcp->tcp.dest = htons ( IMUX_PORT_LOCKDOWND );
682  tcp->tcp.seq = htonl ( imux->tcp_seq );
683  tcp->tcp.ack = htonl ( imux->tcp_ack );
684  tcp->tcp.hlen = ( ( sizeof ( tcp->tcp ) / 4 ) << 4 );
685  tcp->tcp.win = htons ( IMUX_WINDOW );
686 
687  /* Transmit message */
688  if ( ( rc = imux_tx ( imux, iob_disown ( iobuf ) ) ) != 0 )
689  return rc;
690 
691  /* Update TCP sequence */
692  imux->tcp_seq += ( len - sizeof ( *tcp ) );
693 
694  return 0;
695 }
696 
697 /**
698  * Transmit pseudo-TCP SYN
699  *
700  * @v imux USB multiplexer
701  * @ret rc Return status code
702  */
703 static int imux_tx_syn ( struct imux *imux ) {
704  struct io_buffer *iobuf;
705  struct imux_header_tcp *syn;
706  int rc;
707 
708  /* Allocate I/O buffer */
709  iobuf = alloc_iob ( sizeof ( *syn ) );
710  if ( ! iobuf )
711  return -ENOMEM;
712  syn = iob_put ( iobuf, sizeof ( *syn ) );
713 
714  /* Construct TCP SYN message */
715  memset ( syn, 0, sizeof ( *syn ) );
716  syn->tcp.flags = TCP_SYN;
717 
718  /* Transmit message */
719  if ( ( rc = imux_tx_tcp ( imux, iob_disown ( iobuf ) ) ) != 0 )
720  return rc;
721 
722  /* Increment TCP sequence to compensate for SYN */
723  imux->tcp_seq++;
724 
725  return 0;
726 }
727 
728 /**
729  * Open pairing client
730  *
731  * @v imux USB multiplexer
732  * @ret rc Return status code
733  */
734 static int imux_start_pair ( struct imux *imux ) {
735  int rc;
736 
737  /* Disconnect any existing pairing client */
738  intf_restart ( &imux->tcp, -EPIPE );
739 
740  /* Create pairing client */
741  if ( ( rc = ipair_create ( &imux->tcp, imux->flags ) ) != 0 )
742  return rc;
743 
744  return 0;
745 }
746 
747 /**
748  * Receive version message
749  *
750  * @v imux USB multiplexer
751  */
752 static void imux_rx_version ( struct imux *imux ) {
753 
754  /* Reset output sequence */
755  imux->out_seq = 0;
756 
757  /* Send TCP SYN */
759 }
760 
761 /**
762  * Receive log message
763  *
764  * @v imux USB multiplexer
765  * @v hdr Message header
766  * @v len Length of message
767  */
768 static void imux_rx_log ( struct imux *imux, struct imux_header *hdr,
769  size_t len ) {
770  struct imux_header_log *log =
771  container_of ( hdr, struct imux_header_log, hdr );
772  unsigned int level;
773  size_t msg_len;
774  char *tmp;
775 
776  /* Sanity check */
777  if ( len < sizeof ( *log ) ) {
778  DBGC ( imux, "IMUX %p malformed log message:\n", imux );
779  DBGC_HDA ( imux, 0, log, len );
780  return;
781  }
782 
783  /* First byte is the log level, followed by a printable
784  * message with no NUL terminator. Extract the log level,
785  * then shuffle the message down within the buffer and append
786  * a NUL terminator.
787  */
788  msg_len = ( len - sizeof ( *hdr ) );
789  level = log->level;
790  tmp = ( ( void * ) &log->level );
791  memmove ( tmp, &log->msg, msg_len );
792  tmp[msg_len] = '\0';
793 
794  /* Print log message */
795  DBGC ( imux, "IMUX %p <%d>: %s\n", imux, level, tmp );
796 }
797 
798 /**
799  * Receive pseudo-TCP SYN+ACK
800  *
801  * @v imux USB multiplexer
802  */
803 static void imux_rx_syn ( struct imux *imux ) {
804 
805  /* Increment TCP acknowledgement to compensate for SYN */
806  imux->tcp_ack++;
807 
808  /* Start pairing client */
810 }
811 
812 /**
813  * Receive pseudo-TCP message
814  *
815  * @v imux USB multiplexer
816  * @v iobuf I/O buffer
817  */
818 static void imux_rx_tcp ( struct imux *imux, struct io_buffer *iobuf ) {
819  struct imux_header_tcp *tcp = iobuf->data;
820  size_t len = iob_len ( iobuf );
821  int rc;
822 
823  /* Sanity check */
824  if ( len < sizeof ( *tcp ) ) {
825  DBGC ( imux, "IMUX %p malformed TCP message:\n", imux );
826  DBGC_HDA ( imux, 0, tcp, len );
827  goto error;
828  }
829 
830  /* Ignore unexpected packets */
831  if ( tcp->tcp.dest != htons ( imux->port ) ) {
832  DBGC ( imux, "IMUX %p ignoring unexpected TCP port %d:\n",
833  imux, ntohs ( tcp->tcp.dest ) );
834  DBGC_HDA ( imux, 0, tcp, len );
835  goto error;
836  }
837 
838  /* Ignore resets */
839  if ( tcp->tcp.flags & TCP_RST ) {
840  DBGC ( imux, "IMUX %p ignoring TCP RST\n", imux );
841  DBGC2_HDA ( imux, 0, tcp, len );
842  goto error;
843  }
844 
845  /* Record ACK number */
846  imux->tcp_ack = ( ntohl ( tcp->tcp.seq ) + len - sizeof ( *tcp ) );
847 
848  /* Handle received message */
849  if ( tcp->tcp.flags & TCP_SYN ) {
850 
851  /* Received SYN+ACK */
852  imux_rx_syn ( imux );
853 
854  } else {
855 
856  /* Strip header */
857  iob_pull ( iobuf, sizeof ( *tcp ) );
858 
859  /* Deliver via socket */
860  if ( ( rc = xfer_deliver_iob ( &imux->tcp,
861  iob_disown ( iobuf ) ) ) != 0 )
862  goto error;
863  }
864 
865  error:
866  free_iob ( iobuf );
867 }
868 
869 /**
870  * Complete bulk IN transfer
871  *
872  * @v ep USB endpoint
873  * @v iobuf I/O buffer
874  * @v rc Completion status code
875  */
876 static void imux_in_complete ( struct usb_endpoint *ep,
877  struct io_buffer *iobuf, int rc ) {
878  struct imux *imux = container_of ( ep, struct imux, usbnet.in );
879  struct imux_header *hdr = iobuf->data;
880  size_t len = iob_len ( iobuf );
881 
882  /* Ignore packets cancelled when the endpoint closes */
883  if ( ! ep->open )
884  goto drop;
885 
886  /* Report USB errors */
887  if ( rc != 0 ) {
888  DBGC ( imux, "IMUX %p bulk IN failed: %s\n",
889  imux, strerror ( rc ) );
890  goto drop;
891  }
892 
893  /* Sanity check */
894  if ( len < sizeof ( *hdr ) ) {
895  DBGC ( imux, "IMUX %p malformed message:\n", imux );
896  DBGC_HDA ( imux, 0, hdr, len );
897  goto drop;
898  }
899 
900  /* Record input sequence */
901  imux->in_seq = ntohs ( hdr->in_seq );
902 
903  /* Handle according to protocol */
904  DBGCP ( imux, "IMUX %p received:\n", imux );
905  DBGCP_HDA ( imux, 0, hdr, len );
906  switch ( hdr->protocol ) {
907  case htonl ( IMUX_VERSION ):
908  imux_rx_version ( imux );
909  break;
910  case htonl ( IMUX_LOG ):
911  imux_rx_log ( imux, hdr, len );
912  break;
913  case htonl ( IMUX_TCP ):
914  imux_rx_tcp ( imux, iob_disown ( iobuf ) );
915  break;
916  default:
917  DBGC ( imux, "IMUX %p unknown message type %d:\n",
918  imux, ntohl ( hdr->protocol ) );
919  DBGC_HDA ( imux, 0, hdr, len );
920  break;
921  }
922 
923  drop:
924  free_iob ( iobuf );
925 }
926 
927 /** Bulk IN endpoint operations */
930 };
931 
932 /**
933  * Complete bulk OUT transfer
934  *
935  * @v ep USB endpoint
936  * @v iobuf I/O buffer
937  * @v rc Completion status code
938  */
939 static void imux_out_complete ( struct usb_endpoint *ep,
940  struct io_buffer *iobuf, int rc ) {
941  struct imux *imux = container_of ( ep, struct imux, usbnet.out );
942 
943  /* Report USB errors */
944  if ( rc != 0 ) {
945  DBGC ( imux, "IMUX %p bulk OUT failed: %s\n",
946  imux, strerror ( rc ) );
947  goto error;
948  }
949 
950  error:
951  free_iob ( iobuf );
952 }
953 
954 /** Bulk OUT endpoint operations */
957 };
958 
959 /**
960  * Shut down USB multiplexer
961  *
962  * @v imux USB multiplexer
963  */
964 static void imux_shutdown ( struct imux *imux ) {
965 
966  /* Shut down interfaces */
968 
969  /* Close USB network device, if open */
970  if ( process_running ( &imux->process ) ) {
971  process_del ( &imux->process );
972  usbnet_close ( &imux->usbnet );
973  }
974 }
975 
976 /**
977  * Close USB multiplexer
978  *
979  * @v imux USB multiplexer
980  * @v rc Reason for close
981  */
982 static void imux_close ( struct imux *imux, int rc ) {
983  struct iphone *iphone;
984 
985  /* Restart interfaces */
986  intf_restart ( &imux->tcp, rc );
987 
988  /* Record pairing status */
989  imux->rc = rc;
990 
991  /* Trigger link check on any associated iPhones */
992  list_for_each_entry ( iphone, &iphones, list ) {
993  if ( iphone->usb == imux->usb )
995  }
996 
997  /* Retry pairing on any error */
998  if ( rc != 0 ) {
999 
1000  /* Increment port number */
1001  imux->port++;
1002 
1003  /* Request pairing on any retry attempt */
1005 
1006  /* Send new pseudo-TCP SYN */
1007  imux->action = imux_tx_syn;
1008 
1009  DBGC ( imux, "IMUX %p retrying pairing: %s\n",
1010  imux, strerror ( rc ) );
1011  return;
1012  }
1013 
1014  /* Shut down multiplexer on pairing success */
1015  imux_shutdown ( imux );
1016 }
1017 
1018 /**
1019  * Allocate I/O buffer for pseudo-TCP socket
1020  *
1021  * @v imux USB multiplexer
1022  * @v len I/O buffer payload length
1023  * @ret iobuf I/O buffer
1024  */
1025 static struct io_buffer * imux_alloc_iob ( struct imux *imux __unused,
1026  size_t len ) {
1027  struct imux_header_tcp *tcp;
1028  struct io_buffer *iobuf;
1029 
1030  /* Allocate I/O buffer */
1031  iobuf = alloc_iob ( sizeof ( *tcp ) + len );
1032  if ( ! iobuf )
1033  return NULL;
1034 
1035  /* Reserve space for pseudo-TCP message header */
1036  iob_reserve ( iobuf, sizeof ( *tcp ) );
1037 
1038  return iobuf;
1039 }
1040 
1041 /**
1042  * Transmit packet via pseudo-TCP socket
1043  *
1044  * @v imux USB multiplexer
1045  * @v iobuf I/O buffer
1046  * @v meta Data transfer metadata
1047  * @ret rc Return status code
1048  */
1049 static int imux_deliver ( struct imux *imux, struct io_buffer *iobuf,
1050  struct xfer_metadata *meta __unused ) {
1051  struct imux_header_tcp *tcp;
1052 
1053  /* Prepend pseudo-TCP header */
1054  tcp = iob_push ( iobuf, sizeof ( *tcp ) );
1055  memset ( tcp, 0, sizeof ( *tcp ) );
1056  tcp->tcp.flags = TCP_ACK;
1057 
1058  /* Transmit pseudo-TCP packet */
1059  return imux_tx_tcp ( imux, iob_disown ( iobuf ) );
1060 }
1061 
1062 /** Pseudo-TCP socket interface operations */
1064  INTF_OP ( xfer_deliver, struct imux *, imux_deliver ),
1065  INTF_OP ( xfer_alloc_iob, struct imux *, imux_alloc_iob ),
1066  INTF_OP ( intf_close, struct imux *, imux_close ),
1067 };
1068 
1069 /** Pseudo-TCP socket interface descriptor */
1071  INTF_DESC ( struct imux, tcp, imux_tcp_operations );
1072 
1073 /**
1074  * Multiplexer process
1075  *
1076  * @v imux USB multiplexer
1077  */
1078 static void imux_step ( struct imux *imux ) {
1079  int rc;
1080 
1081  /* Poll USB bus */
1082  usb_poll ( imux->bus );
1083 
1084  /* Do nothing more if multiplexer has been closed */
1085  if ( ! process_running ( &imux->process ) )
1086  return;
1087 
1088  /* Refill endpoints */
1089  if ( ( rc = usbnet_refill ( &imux->usbnet ) ) != 0 ) {
1090  /* Wait for next poll */
1091  return;
1092  }
1093 
1094  /* Perform pending action, if any */
1095  if ( imux->action ) {
1096  if ( ( rc = imux->action ( imux ) ) != 0 )
1097  imux_close ( imux, rc );
1098  imux->action = NULL;
1099  }
1100 }
1101 
1102 /** Multiplexer process descriptor */
1104  PROC_DESC ( struct imux, process, imux_step );
1105 
1106 /**
1107  * Probe device
1108  *
1109  * @v func USB function
1110  * @v config Configuration descriptor
1111  * @ret rc Return status code
1112  */
1113 static int imux_probe ( struct usb_function *func,
1114  struct usb_configuration_descriptor *config ) {
1115  struct usb_device *usb = func->usb;
1116  struct imux *imux;
1117  int rc;
1118 
1119  /* Allocate and initialise structure */
1120  imux = zalloc ( sizeof ( *imux ) );
1121  if ( ! imux ) {
1122  rc = -ENOMEM;
1123  goto err_alloc;
1124  }
1125  ref_init ( &imux->refcnt, NULL );
1126  imux->usb = usb;
1127  imux->bus = usb->port->hub->bus;
1136 
1137  /* Describe USB network device */
1138  if ( ( rc = usbnet_describe ( &imux->usbnet, config ) ) != 0 ) {
1139  DBGC ( imux, "IMUX %p could not describe: %s\n",
1140  imux, strerror ( rc ) );
1141  goto err_describe;
1142  }
1143 
1144  /* Open USB network device */
1145  if ( ( rc = usbnet_open ( &imux->usbnet ) ) != 0 ) {
1146  DBGC ( imux, "IMUX %p could not open: %s\n",
1147  imux, strerror ( rc ) );
1148  goto err_open;
1149  }
1150 
1151  /* Start polling process */
1152  process_add ( &imux->process );
1153 
1154  /* Add to list of multiplexers */
1155  list_add ( &imux->list, &imuxes );
1156 
1157  usb_func_set_drvdata ( func, imux );
1158  return 0;
1159 
1160  list_del ( &imux->list );
1161  imux_shutdown ( imux );
1162  err_open:
1163  err_describe:
1164  ref_put ( &imux->refcnt );
1165  err_alloc:
1166  return rc;
1167 }
1168 
1169 /**
1170  * Remove device
1171  *
1172  * @v func USB function
1173  */
1174 static void imux_remove ( struct usb_function *func ) {
1175  struct imux *imux = usb_func_get_drvdata ( func );
1176 
1177  list_del ( &imux->list );
1178  imux_shutdown ( imux );
1179  ref_put ( &imux->refcnt );
1180 }
1181 
1182 /** USB multiplexer device IDs */
1183 static struct usb_device_id imux_ids[] = {
1184  {
1185  .name = "imux",
1186  .vendor = 0x05ac,
1187  .product = USB_ANY_ID,
1188  },
1189 };
1190 
1191 /** USB multiplexer driver */
1192 struct usb_driver imux_driver __usb_driver = {
1193  .ids = imux_ids,
1194  .id_count = ( sizeof ( imux_ids ) / sizeof ( imux_ids[0] ) ),
1195  .class = USB_CLASS_ID ( 0xff, 0xfe, 0x02 ),
1196  .score = USB_SCORE_NORMAL,
1197  .probe = imux_probe,
1198  .remove = imux_remove,
1199 };
1200 
1201 /******************************************************************************
1202  *
1203  * iPhone pairing client
1204  *
1205  ******************************************************************************
1206  */
1207 
1208 /** Common prefix for all pairing messages */
1209 static const char ipair_prefix[] =
1210  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1211  "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
1212  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
1213  "<plist version=\"1.0\">\n"
1214  "<dict>\n"
1215  "<key>Label</key>\n"
1216  "<string>iPXE</string>\n"
1217  "<key>Request</key>\n";
1218 
1219 /** Common suffix for all pairing messages */
1220 static const char ipair_suffix[] =
1221  "</dict>\n"
1222  "</plist>\n";
1223 
1224 /** Arbitrary system BUID used for pairing */
1225 static const char ipair_system_buid[] = "E4DB92D2-248A-469A-AC34-92045D07E695";
1226 
1227 /** Arbitrary host ID used for pairing */
1228 static const char ipair_host_id[] = "93CEBC27-8457-4804-9108-F42549DF6143";
1229 
1230 static int ipair_tx_pubkey ( struct ipair *ipair );
1231 static int ipair_rx_pubkey ( struct ipair *ipair, char *msg );
1232 static int ipair_tx_pair ( struct ipair *ipair );
1233 static int ipair_rx_pair ( struct ipair *ipair, char *msg );
1234 static int ipair_tx_session ( struct ipair *ipair );
1235 static int ipair_rx_session ( struct ipair *ipair, char *msg );
1236 
1237 /**
1238  * Free pairing client
1239  *
1240  * @v refcnt Reference counter
1241  */
1242 static void ipair_free ( struct refcnt *refcnt ) {
1243  struct ipair *ipair = container_of ( refcnt, struct ipair, refcnt );
1244 
1245  icert_free ( &ipair->icert );
1246  free ( ipair );
1247 }
1248 
1249 /**
1250  * Shut down pairing client
1251  *
1252  * @v ipair Pairing client
1253  * @v rc Reason for close
1254  */
1255 static void ipair_close ( struct ipair *ipair, int rc ) {
1256 
1257  /* Shut down interfaces */
1258  intf_shutdown ( &ipair->xfer, rc );
1259 
1260  /* Stop timer */
1261  stop_timer ( &ipair->timer );
1262 }
1263 
1264 /**
1265  * Transmit XML message
1266  *
1267  * @v ipair Pairing client
1268  * @v fmt Format string
1269  * @v ... Arguments
1270  * @ret rc Return status code
1271  */
1272 static int __attribute__ (( format ( printf, 2, 3 ) ))
1273 ipair_tx ( struct ipair *ipair, const char *fmt, ... ) {
1274  struct io_buffer *iobuf;
1275  struct ipair_header *hdr;
1276  va_list args;
1277  size_t len;
1278  char *msg;
1279  int rc;
1280 
1281  /* Calculate length of formatted string */
1282  va_start ( args, fmt );
1283  len = ( vsnprintf ( NULL, 0, fmt, args ) + 1 /* NUL */ );
1284  va_end ( args );
1285 
1286  /* Allocate I/O buffer */
1287  iobuf = xfer_alloc_iob ( &ipair->xfer, ( sizeof ( *hdr ) + len ) );
1288  if ( ! iobuf )
1289  return -ENOMEM;
1290  hdr = iob_put ( iobuf, sizeof ( *hdr ) );
1291 
1292  /* Construct XML message */
1293  memset ( hdr, 0, sizeof ( *hdr ) );
1294  hdr->len = htonl ( len );
1295  msg = iob_put ( iobuf, len );
1296  va_start ( args, fmt );
1297  vsnprintf ( msg, len, fmt, args );
1298  va_end ( args );
1299  DBGC2 ( ipair, "IPAIR %p transmitting:\n%s\n", ipair, msg );
1300 
1301  /* Transmit message */
1302  if ( ( rc = xfer_deliver_iob ( &ipair->xfer,
1303  iob_disown ( iobuf ) ) ) != 0 )
1304  return rc;
1305 
1306  return 0;
1307 }
1308 
1309 /**
1310  * Receive XML message payload
1311  *
1312  * @v ipair Pairing client
1313  * @v msg Message payload
1314  * @v len Length of message
1315  * @ret rc Return status code
1316  */
1317 static int ipair_rx ( struct ipair *ipair, char *msg, size_t len ) {
1318  int ( * rx ) ( struct ipair *ipair, char *msg );
1319  int rc;
1320 
1321  /* Ignore empty messages */
1322  if ( ! len )
1323  return 0;
1324 
1325  /* Sanity check */
1326  if ( ( msg[ len - 1 ] != '\0' ) && ( msg[ len - 1 ] != '\n' ) ) {
1327  DBGC ( ipair, "IPAIR %p malformed XML:\n", ipair );
1328  DBGC_HDA ( ipair, 0, msg, len );
1329  return -EPROTO;
1330  }
1331 
1332  /* Add NUL terminator (potentially overwriting final newline) */
1333  msg[ len - 1 ] = '\0';
1334  DBGC2 ( ipair, "IPAIR %p received:\n%s\n\n", ipair, msg );
1335 
1336  /* Handle according to current state */
1337  rx = ipair->rx;
1338  if ( ! rx ) {
1339  DBGC ( ipair, "IPAIR %p unexpected XML:\n%s\n", ipair, msg );
1340  return -EPROTO;
1341  }
1342  ipair->rx = NULL;
1343  if ( ( rc = rx ( ipair, msg ) ) != 0 )
1344  return rc;
1345 
1346  return 0;
1347 }
1348 
1349 /**
1350  * Locate XML tag
1351  *
1352  * @v ipair Pairing client
1353  * @v msg XML message
1354  * @v tag Tag name
1355  * @ret start Start of tag content
1356  * @ret end End of tag content
1357  * @ret rc Return status code
1358  */
1359 static int ipair_tag ( struct ipair *ipair, const char *msg, const char *tag,
1360  char **start, char **end ) {
1361  char buf[ 2 /* "</" */ + strlen ( tag ) + 1 /* ">" */ + 1 /* NUL */ ];
1362 
1363  /* Locate opening tag */
1364  sprintf ( buf, "<%s>", tag );
1365  *start = strstr ( msg, buf );
1366  if ( ! *start )
1367  return -ENOENT;
1368  *start += strlen ( buf );
1369 
1370  /* Locate closing tag */
1371  sprintf ( buf, "</%s>", tag );
1372  *end = strstr ( *start, buf );
1373  if ( ! *end ) {
1374  DBGC ( ipair, "IPAIR %p missing closing tag %s in:\n%s\n",
1375  ipair, buf, msg );
1376  return -ENOENT;
1377  }
1378 
1379  return 0;
1380 }
1381 
1382 /**
1383  * Locate XML property list dictionary value
1384  *
1385  * @v ipair Pairing client
1386  * @v msg XML message
1387  * @v key Key name
1388  * @v type Key type
1389  * @ret start Start of value content
1390  * @ret end End of value content
1391  * @ret rc Return status code
1392  */
1393 static int ipair_key ( struct ipair *ipair, const char *msg, const char *key,
1394  const char *type, char **start, char **end ) {
1395  int rc;
1396 
1397  /* Iterate over keys */
1398  while ( 1 ) {
1399 
1400  /* Locate key */
1401  if ( ( rc = ipair_tag ( ipair, msg, "key", start,
1402  end ) ) != 0 )
1403  return rc;
1404  msg = *end;
1405 
1406  /* Check key name */
1407  if ( memcmp ( *start, key, ( *end - *start ) ) != 0 )
1408  continue;
1409 
1410  /* Locate value */
1411  return ipair_tag ( ipair, msg, type, start, end );
1412  }
1413 }
1414 
1415 /**
1416  * Transmit DevicePublicKey message
1417  *
1418  * @v ipair Pairing client
1419  * @ret rc Return status code
1420  */
1421 static int ipair_tx_pubkey ( struct ipair *ipair ) {
1422  int rc;
1423 
1424  /* Transmit message */
1425  if ( ( rc = ipair_tx ( ipair,
1426  "%s"
1427  "<string>GetValue</string>\n"
1428  "<key>Key</key>\n"
1429  "<string>DevicePublicKey</string>\n"
1430  "%s",
1431  ipair_prefix, ipair_suffix ) ) != 0 )
1432  return rc;
1433 
1434  return 0;
1435 }
1436 
1437 /**
1438  * Receive DevicePublicKey message
1439  *
1440  * @v ipair Pairing client
1441  * @v msg XML message
1442  * @ret rc Return status code
1443  */
1444 static int ipair_rx_pubkey ( struct ipair *ipair, char *msg ) {
1445  struct asn1_cursor *key;
1446  char *data;
1447  char *end;
1448  char *decoded;
1449  size_t max_len;
1450  int len;
1451  int next;
1452  int rc;
1453 
1454  /* Locate "Value" value */
1455  if ( ( rc = ipair_key ( ipair, msg, "Value", "data", &data,
1456  &end ) ) != 0 ) {
1457  DBGC ( ipair, "IPAIR %p unexpected public key message:\n%s\n",
1458  ipair, msg );
1459  goto err_tag;
1460  }
1461  *end = '\0';
1462 
1463  /* Decode outer layer of Base64 */
1464  max_len = base64_decoded_max_len ( data );
1465  decoded = malloc ( max_len );
1466  if ( ! decoded ) {
1467  rc = -ENOMEM;
1468  goto err_alloc;
1469  }
1470  len = base64_decode ( data, decoded, max_len );
1471  if ( len < 0 ) {
1472  rc = len;
1473  DBGC ( ipair, "IPAIR %p invalid outer public key:\n%s\n",
1474  ipair, data );
1475  goto err_decode;
1476  }
1477 
1478  /* Decode inner layer of Base64 */
1479  next = pem_asn1 ( virt_to_user ( decoded ), len, 0, &key );
1480  if ( next < 0 ) {
1481  rc = next;
1482  DBGC ( ipair, "IPAIR %p invalid inner public key:\n%s\n",
1483  ipair, decoded );
1484  goto err_asn1;
1485  }
1486  DBGC ( ipair, "IPAIR %p received public key\n", ipair );
1487  DBGC2_HDA ( ipair, 0, key->data, key->len );
1488 
1489  /* Construct certificates */
1490  if ( ( rc = icert_certs ( &ipair->icert, key ) ) != 0 )
1491  goto err_certs;
1492 
1493  /* Send session request or pair request as applicable */
1494  if ( ipair->flags & IPAIR_REQUEST ) {
1495  ipair->tx = ipair_tx_pair;
1496  ipair->rx = ipair_rx_pair;
1497  } else {
1500  }
1502 
1503  /* Free key */
1504  free ( key );
1505 
1506  /* Free intermediate Base64 */
1507  free ( decoded );
1508 
1509  return 0;
1510 
1511  err_certs:
1512  free ( key );
1513  err_asn1:
1514  err_decode:
1515  free ( decoded );
1516  err_alloc:
1517  err_tag:
1518  return rc;
1519 }
1520 
1521 /**
1522  * Transmit Pair message
1523  *
1524  * @v ipair Pairing client
1525  * @ret rc Return status code
1526  */
1527 static int ipair_tx_pair ( struct ipair *ipair ) {
1528  char *root;
1529  char *host;
1530  char *device;
1531  int rc;
1532 
1533  /* Construct doubly encoded certificates */
1534  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.root,
1535  &root ) ) != 0 )
1536  goto err_root;
1537  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.host,
1538  &host ) ) != 0 )
1539  goto err_host;
1540  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.device,
1541  &device ) ) != 0 )
1542  goto err_device;
1543 
1544  /* Transmit message */
1545  if ( ( rc = ipair_tx ( ipair,
1546  "%s"
1547  "<string>Pair</string>\n"
1548  "<key>PairRecord</key>\n"
1549  "<dict>\n"
1550  "<key>RootCertificate</key>\n"
1551  "<data>%s</data>\n"
1552  "<key>HostCertificate</key>\n"
1553  "<data>%s</data>\n"
1554  "<key>DeviceCertificate</key>\n"
1555  "<data>%s</data>\n"
1556  "<key>SystemBUID</key>\n"
1557  "<string>%s</string>\n"
1558  "<key>HostID</key>\n"
1559  "<string>%s</string>\n"
1560  "</dict>\n"
1561  "<key>ProtocolVersion</key>\n"
1562  "<string>2</string>\n"
1563  "<key>PairingOptions</key>\n"
1564  "<dict>\n"
1565  "<key>ExtendedPairingErrors</key>\n"
1566  "<true/>\n"
1567  "</dict>\n"
1568  "%s",
1569  ipair_prefix, root, host, device,
1571  ipair_suffix
1572  ) ) != 0 )
1573  goto err_tx;
1574 
1575  err_tx:
1576  free ( device );
1577  err_device:
1578  free ( host );
1579  err_host:
1580  free ( root );
1581  err_root:
1582  return rc;
1583 }
1584 
1585 /**
1586  * Receive Pair message error
1587  *
1588  * @v ipair Pairing client
1589  * @v error Pairing error
1590  * @ret rc Return status code
1591  */
1592 static int ipair_rx_pair_error ( struct ipair *ipair, char *error ) {
1593 
1594  /* Check for actual errors */
1595  if ( strcmp ( error, "PairingDialogResponsePending" ) != 0 ) {
1596  DBGC ( ipair, "IPAIR %p pairing error \"%s\"\n", ipair, error );
1597  return -EPERM;
1598  }
1599 
1600  /* Retransmit pairing request */
1601  ipair->tx = ipair_tx_pair;
1602  ipair->rx = ipair_rx_pair;
1604 
1605  DBGC ( ipair, "IPAIR %p waiting for pairing dialog\n", ipair );
1606  return 0;
1607 }
1608 
1609 /**
1610  * Receive Pair message
1611  *
1612  * @v ipair Pairing client
1613  * @v msg XML message
1614  * @ret rc Return status code
1615  */
1616 static int ipair_rx_pair ( struct ipair *ipair, char *msg ) {
1617  char *error;
1618  char *escrow;
1619  char *end;
1620  int rc;
1621 
1622  /* Check for pairing errors */
1623  if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1624  &end ) ) == 0 ) {
1625  *end = '\0';
1626  return ipair_rx_pair_error ( ipair, error );
1627  }
1628 
1629  /* Get EscrowBag */
1630  if ( ( rc = ipair_key ( ipair, msg, "EscrowBag", "data", &escrow,
1631  &end ) ) != 0 ) {
1632  DBGC ( ipair, "IPAIR %p unexpected pairing response:\n%s\n",
1633  ipair, msg );
1634  return rc;
1635  }
1636  DBGC ( ipair, "IPAIR %p pairing successful\n", ipair );
1637 
1638  /* Send session request */
1642 
1643  return 0;
1644 }
1645 
1646 /**
1647  * Transmit StartSession message
1648  *
1649  * @v ipair Pairing client
1650  * @ret rc Return status code
1651  */
1652 static int ipair_tx_session ( struct ipair *ipair ) {
1653  int rc;
1654 
1655  /* Transmit message */
1656  if ( ( rc = ipair_tx ( ipair,
1657  "%s"
1658  "<string>StartSession</string>\n"
1659  "<key>SystemBUID</key>\n"
1660  "<string>%s</string>\n"
1661  "<key>HostID</key>\n"
1662  "<string>%s</string>\n"
1663  "%s",
1666  ) ) != 0 )
1667  return rc;
1668 
1669  return 0;
1670 }
1671 
1672 /**
1673  * Receive StartSession message error
1674  *
1675  * @v ipair Pairing client
1676  * @v error Pairing error
1677  * @ret rc Return status code
1678  */
1679 static int ipair_rx_session_error ( struct ipair *ipair, char *error ) {
1680 
1681  /* Check for actual errors */
1682  if ( strcmp ( error, "InvalidHostID" ) != 0 ) {
1683  DBGC ( ipair, "IPAIR %p session error \"%s\"\n", ipair, error );
1684  return -EPERM;
1685  }
1686 
1687  /* Transmit pairing request */
1688  ipair->tx = ipair_tx_pair;
1689  ipair->rx = ipair_rx_pair;
1691 
1692  DBGC ( ipair, "IPAIR %p unknown host: requesting pairing\n", ipair );
1693  return 0;
1694 }
1695 
1696 /**
1697  * Receive StartSession message
1698  *
1699  * @v ipair Pairing client
1700  * @v msg XML message
1701  * @ret rc Return status code
1702  */
1703 static int ipair_rx_session ( struct ipair *ipair, char *msg ) {
1704  char *error;
1705  char *session;
1706  char *end;
1707  int rc;
1708 
1709  /* Check for session errors */
1710  if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1711  &end ) ) == 0 ) {
1712  *end = '\0';
1713  return ipair_rx_session_error ( ipair, error );
1714  }
1715 
1716  /* Check for session ID */
1717  if ( ( rc = ipair_key ( ipair, msg, "SessionID", "string", &session,
1718  &end ) ) != 0 ) {
1719  DBGC ( ipair, "IPAIR %p unexpected session response:\n%s\n",
1720  ipair, msg );
1721  return rc;
1722  }
1723  *end = '\0';
1724  DBGC ( ipair, "IPAIR %p starting session \"%s\"\n", ipair, session );
1725 
1726  /* Start TLS */
1727  if ( ( rc = add_tls ( &ipair->xfer, "iPhone", &icert_root,
1728  ipair->icert.key ) ) != 0 ) {
1729  DBGC ( ipair, "IPAIR %p could not start TLS: %s\n",
1730  ipair, strerror ( rc ) );
1731  return rc;
1732  }
1733 
1734  /* Record that TLS has been started */
1735  ipair->flags |= IPAIR_TLS;
1736 
1737  return 0;
1738 }
1739 
1740 /**
1741  * Handle window change notification
1742  *
1743  * @v ipair Pairing client
1744  */
1745 static void ipair_window_changed ( struct ipair *ipair ) {
1746 
1747  /* Report pairing as complete once TLS session has been established */
1748  if ( ( ipair->flags & IPAIR_TLS ) && xfer_window ( &ipair->xfer ) ) {
1749 
1750  /* Sanity checks */
1753  assert ( ! x509_is_valid ( ipair->icert.root, NULL ) );
1754  assert ( ! x509_is_valid ( ipair->icert.host, NULL ) );
1755  assert ( ! x509_is_valid ( ipair->icert.device, NULL ) );
1756 
1757  /* Report pairing as complete */
1758  DBGC ( ipair, "IPAIR %p established TLS session\n", ipair );
1759  ipair_close ( ipair, 0 );
1760  return;
1761  }
1762 }
1763 
1764 /**
1765  * Handle received data
1766  *
1767  * @v ipair Pairing client
1768  * @v iobuf I/O buffer
1769  * @v meta Data transfer metadata
1770  * @ret rc Return status code
1771  */
1772 static int ipair_deliver ( struct ipair *ipair, struct io_buffer *iobuf,
1773  struct xfer_metadata *meta __unused ) {
1774  struct ipair_header *hdr;
1775  int rc;
1776 
1777  /* Strip header (which may appear in a separate packet) */
1778  if ( ( ! ( ipair->flags & IPAIR_RX_LEN ) ) &&
1779  ( iob_len ( iobuf ) >= sizeof ( *hdr ) ) ) {
1780  iob_pull ( iobuf, sizeof ( *hdr ) );
1781  ipair->flags |= IPAIR_RX_LEN;
1782  }
1783 
1784  /* Clear received header flag if we have a message */
1785  if ( iob_len ( iobuf ) )
1786  ipair->flags &= ~IPAIR_RX_LEN;
1787 
1788  /* Receive message */
1789  if ( ( rc = ipair_rx ( ipair, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
1790  goto error;
1791 
1792  /* Free I/O buffer */
1793  free_iob ( iobuf );
1794 
1795  return 0;
1796 
1797  error:
1798  ipair_close ( ipair, rc );
1799  free_iob ( iobuf );
1800  return rc;
1801 }
1802 
1803 /**
1804  * Pairing transmission timer
1805  *
1806  * @v timer Retransmission timer
1807  * @v over Failure indicator
1808  */
1809 static void ipair_expired ( struct retry_timer *timer, int over __unused ) {
1810  struct ipair *ipair = container_of ( timer, struct ipair, timer );
1811  int ( * tx ) ( struct ipair *ipair );
1812  int rc;
1813 
1814  /* Sanity check */
1815  tx = ipair->tx;
1816  assert ( tx != NULL );
1817 
1818  /* Clear pending transmission */
1819  ipair->tx = NULL;
1820 
1821  /* Transmit data, if applicable */
1822  if ( ( rc = tx ( ipair ) ) != 0 )
1823  ipair_close ( ipair, rc );
1824 }
1825 
1826 /** Pairing client interface operations */
1828  INTF_OP ( xfer_deliver, struct ipair *, ipair_deliver ),
1830  INTF_OP ( intf_close, struct ipair *, ipair_close ),
1831 };
1832 
1833 /** Pairing client interface descriptor */
1835  INTF_DESC ( struct ipair, xfer, ipair_xfer_operations );
1836 
1837 /**
1838  * Create a pairing client
1839  *
1840  * @v xfer Data transfer interface
1841  * @v flags Initial state flags
1842  * @ret rc Return status code
1843  */
1844 static int ipair_create ( struct interface *xfer, unsigned int flags ) {
1845  struct ipair *ipair;
1846  int rc;
1847 
1848  /* Allocate and initialise structure */
1849  ipair = zalloc ( sizeof ( *ipair ) );
1850  if ( ! ipair ) {
1851  rc = -ENOMEM;
1852  goto err_alloc;
1853  }
1856  timer_init ( &ipair->timer, ipair_expired, &ipair->refcnt );
1859  ipair->flags = flags;
1860 
1861  /* Schedule initial transmission */
1863 
1864  /* Attach to parent interface, mortalise self, and return */
1865  intf_plug_plug ( &ipair->xfer, xfer );
1866  ref_put ( &ipair->refcnt );
1867  return 0;
1868 
1869  ref_put ( &ipair->refcnt );
1870  err_alloc:
1871  return rc;
1872 }
1873 
1874 /******************************************************************************
1875  *
1876  * iPhone USB networking
1877  *
1878  ******************************************************************************
1879  */
1880 
1881 /**
1882  * Complete bulk IN transfer
1883  *
1884  * @v ep USB endpoint
1885  * @v iobuf I/O buffer
1886  * @v rc Completion status code
1887  */
1888 static void iphone_in_complete ( struct usb_endpoint *ep,
1889  struct io_buffer *iobuf, int rc ) {
1890  struct iphone *iphone = container_of ( ep, struct iphone, usbnet.in );
1891  struct net_device *netdev = iphone->netdev;
1892 
1893  /* Profile receive completions */
1894  profile_start ( &iphone_in_profiler );
1895 
1896  /* Ignore packets cancelled when the endpoint closes */
1897  if ( ! ep->open )
1898  goto ignore;
1899 
1900  /* Record USB errors against the network device */
1901  if ( rc != 0 ) {
1902  DBGC ( iphone, "IPHONE %p bulk IN failed: %s\n",
1903  iphone, strerror ( rc ) );
1904  goto error;
1905  }
1906 
1907  /* Strip padding */
1908  if ( iob_len ( iobuf ) < IPHONE_IN_PAD ) {
1909  DBGC ( iphone, "IPHONE %p malformed bulk IN:\n", iphone );
1910  DBGC_HDA ( iphone, 0, iobuf->data, iob_len ( iobuf ) );
1911  rc = -EINVAL;
1912  goto error;
1913  }
1914  iob_pull ( iobuf, IPHONE_IN_PAD );
1915 
1916  /* Hand off to network stack */
1917  netdev_rx ( netdev, iob_disown ( iobuf ) );
1918 
1919  profile_stop ( &iphone_in_profiler );
1920  return;
1921 
1922  error:
1923  netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
1924  ignore:
1925  free_iob ( iobuf );
1926 }
1927 
1928 /** Bulk IN endpoint operations */
1931 };
1932 
1933 /**
1934  * Transmit packet
1935  *
1936  * @v iphone iPhone device
1937  * @v iobuf I/O buffer
1938  * @ret rc Return status code
1939  */
1940 static int iphone_out_transmit ( struct iphone *iphone,
1941  struct io_buffer *iobuf ) {
1942  int rc;
1943 
1944  /* Profile transmissions */
1945  profile_start ( &iphone_out_profiler );
1946 
1947  /* Enqueue I/O buffer */
1948  if ( ( rc = usb_stream ( &iphone->usbnet.out, iobuf, 1 ) ) != 0 )
1949  return rc;
1950 
1951  profile_stop ( &iphone_out_profiler );
1952  return 0;
1953 }
1954 
1955 /**
1956  * Complete bulk OUT transfer
1957  *
1958  * @v ep USB endpoint
1959  * @v iobuf I/O buffer
1960  * @v rc Completion status code
1961  */
1962 static void iphone_out_complete ( struct usb_endpoint *ep,
1963  struct io_buffer *iobuf, int rc ) {
1964  struct iphone *iphone = container_of ( ep, struct iphone, usbnet.out );
1965  struct net_device *netdev = iphone->netdev;
1966 
1967  /* Report TX completion */
1968  netdev_tx_complete_err ( netdev, iobuf, rc );
1969 }
1970 
1971 /** Bulk OUT endpoint operations */
1974 };
1975 
1976 /**
1977  * Check pairing status
1978  *
1979  * @v iphone iPhone device
1980  * @ret rc Return status code
1981  */
1982 static int iphone_check_pair ( struct iphone *iphone ) {
1983  struct imux *imux;
1984 
1985  /* Find corresponding USB multiplexer */
1986  list_for_each_entry ( imux, &imuxes, list ) {
1987  if ( imux->usb == iphone->usb )
1988  return imux->rc;
1989  }
1990 
1991  return -EPIPE_NO_MUX;
1992 }
1993 
1994 /**
1995  * Check link status
1996  *
1997  * @v netdev Network device
1998  */
1999 static void iphone_check_link ( struct net_device *netdev ) {
2000  struct iphone *iphone = netdev->priv;
2001  struct usb_device *usb = iphone->usb;
2002  uint8_t status;
2003  int rc;
2004 
2005  /* Check pairing status */
2006  if ( ( rc = iphone_check_pair ( iphone ) ) != 0 )
2007  goto err_pair;
2008 
2009  /* Get link status */
2010  if ( ( rc = usb_control ( usb, IPHONE_GET_LINK, 0, 0, &status,
2011  sizeof ( status ) ) ) != 0 ) {
2012  DBGC ( iphone, "IPHONE %p could not get link status: %s\n",
2013  iphone, strerror ( rc ) );
2014  goto err_control;
2015  }
2016 
2017  /* Check link status */
2018  if ( status != IPHONE_LINK_UP ) {
2019  rc = -ENOTCONN_STATUS ( status );
2020  goto err_status;
2021  }
2022 
2023  /* Success */
2024  rc = 0;
2025 
2026  err_status:
2027  err_control:
2028  err_pair:
2029  /* Report link status. Since we have to check the link
2030  * periodically (due to an absence of an interrupt endpoint),
2031  * do this only if the link status has actually changed.
2032  */
2033  if ( rc != netdev->link_rc ) {
2034  if ( rc == 0 ) {
2035  DBGC ( iphone, "IPHONE %p link up\n", iphone );
2036  } else {
2037  DBGC ( iphone, "IPHONE %p link down: %s\n",
2038  iphone, strerror ( rc ) );
2039  }
2040  netdev_link_err ( netdev, rc );
2041  }
2042 }
2043 
2044 /**
2045  * Periodically update link status
2046  *
2047  * @v timer Link status timer
2048  * @v over Failure indicator
2049  */
2050 static void iphone_expired ( struct retry_timer *timer, int over __unused ) {
2051  struct iphone *iphone = container_of ( timer, struct iphone, timer );
2052  struct net_device *netdev = iphone->netdev;
2053 
2054  /* Check link status */
2056 
2057  /* Restart timer, if device is open */
2058  if ( netdev_is_open ( netdev ) )
2060 }
2061 
2062 /**
2063  * Open network device
2064  *
2065  * @v netdev Network device
2066  * @ret rc Return status code
2067  */
2068 static int iphone_open ( struct net_device *netdev ) {
2069  struct iphone *iphone = netdev->priv;
2070  int rc;
2071 
2072  /* Open USB network device */
2073  if ( ( rc = usbnet_open ( &iphone->usbnet ) ) != 0 ) {
2074  DBGC ( iphone, "IPHONE %p could not open: %s\n",
2075  iphone, strerror ( rc ) );
2076  goto err_open;
2077  }
2078 
2079  /* Start the link status check timer */
2081 
2082  return 0;
2083 
2084  usbnet_close ( &iphone->usbnet );
2085  err_open:
2086  return rc;
2087 }
2088 
2089 /**
2090  * Close network device
2091  *
2092  * @v netdev Network device
2093  */
2094 static void iphone_close ( struct net_device *netdev ) {
2095  struct iphone *iphone = netdev->priv;
2096 
2097  /* Stop the link status check timer */
2098  stop_timer ( &iphone->timer );
2099 
2100  /* Close USB network device */
2101  usbnet_close ( &iphone->usbnet );
2102 }
2103 
2104 /**
2105  * Transmit packet
2106  *
2107  * @v netdev Network device
2108  * @v iobuf I/O buffer
2109  * @ret rc Return status code
2110  */
2111 static int iphone_transmit ( struct net_device *netdev,
2112  struct io_buffer *iobuf ) {
2113  struct iphone *iphone = netdev->priv;
2114  int rc;
2115 
2116  /* Transmit packet */
2117  if ( ( rc = iphone_out_transmit ( iphone, iobuf ) ) != 0 )
2118  return rc;
2119 
2120  return 0;
2121 }
2122 
2123 /**
2124  * Poll for completed and received packets
2125  *
2126  * @v netdev Network device
2127  */
2128 static void iphone_poll ( struct net_device *netdev ) {
2129  struct iphone *iphone = netdev->priv;
2130  int rc;
2131 
2132  /* Poll USB bus */
2133  usb_poll ( iphone->bus );
2134 
2135  /* Refill endpoints */
2136  if ( ( rc = usbnet_refill ( &iphone->usbnet ) ) != 0 )
2137  netdev_rx_err ( netdev, NULL, rc );
2138 }
2139 
2140 /** iPhone network device operations */
2142  .open = iphone_open,
2143  .close = iphone_close,
2144  .transmit = iphone_transmit,
2145  .poll = iphone_poll,
2146 };
2147 
2148 /**
2149  * Probe device
2150  *
2151  * @v func USB function
2152  * @v config Configuration descriptor
2153  * @ret rc Return status code
2154  */
2155 static int iphone_probe ( struct usb_function *func,
2156  struct usb_configuration_descriptor *config ) {
2157  struct usb_device *usb = func->usb;
2158  struct net_device *netdev;
2159  struct iphone *iphone;
2160  int rc;
2161 
2162  /* Allocate and initialise structure */
2163  netdev = alloc_etherdev ( sizeof ( *iphone ) );
2164  if ( ! netdev ) {
2165  rc = -ENOMEM;
2166  goto err_alloc;
2167  }
2169  netdev->dev = &func->dev;
2170  iphone = netdev->priv;
2171  memset ( iphone, 0, sizeof ( *iphone ) );
2172  iphone->usb = usb;
2173  iphone->bus = usb->port->hub->bus;
2174  iphone->netdev = netdev;
2179  timer_init ( &iphone->timer, iphone_expired, &netdev->refcnt );
2180  DBGC ( iphone, "IPHONE %p on %s\n", iphone, func->name );
2181 
2182  /* Describe USB network device */
2183  if ( ( rc = usbnet_describe ( &iphone->usbnet, config ) ) != 0 ) {
2184  DBGC ( iphone, "IPHONE %p could not describe: %s\n",
2185  iphone, strerror ( rc ) );
2186  goto err_describe;
2187  }
2188 
2189  /* Fetch MAC address */
2190  if ( ( rc = usb_control ( usb, IPHONE_GET_MAC, 0, 0, netdev->hw_addr,
2191  ETH_ALEN ) ) != 0 ) {
2192  DBGC ( iphone, "IPHONE %p could not fetch MAC address: %s\n",
2193  iphone, strerror ( rc ) );
2194  goto err_fetch_mac;
2195  }
2196 
2197  /* Register network device */
2198  if ( ( rc = register_netdev ( netdev ) ) != 0 )
2199  goto err_register;
2200 
2201  /* Set initial link status */
2203 
2204  /* Add to list of iPhone network devices */
2205  list_add ( &iphone->list, &iphones );
2206 
2207  usb_func_set_drvdata ( func, iphone );
2208  return 0;
2209 
2210  list_del ( &iphone->list );
2212  err_register:
2213  err_fetch_mac:
2214  err_describe:
2215  netdev_nullify ( netdev );
2216  netdev_put ( netdev );
2217  err_alloc:
2218  return rc;
2219 }
2220 
2221 /**
2222  * Remove device
2223  *
2224  * @v func USB function
2225  */
2226 static void iphone_remove ( struct usb_function *func ) {
2227  struct iphone *iphone = usb_func_get_drvdata ( func );
2228  struct net_device *netdev = iphone->netdev;
2229 
2230  list_del ( &iphone->list );
2232  netdev_nullify ( netdev );
2233  netdev_put ( netdev );
2234 }
2235 
2236 /** iPhone device IDs */
2237 static struct usb_device_id iphone_ids[] = {
2238  {
2239  .name = "iphone",
2240  .vendor = 0x05ac,
2241  .product = USB_ANY_ID,
2242  },
2243 };
2244 
2245 /** iPhone driver */
2246 struct usb_driver iphone_driver __usb_driver = {
2247  .ids = iphone_ids,
2248  .id_count = ( sizeof ( iphone_ids ) / sizeof ( iphone_ids[0] ) ),
2249  .class = USB_CLASS_ID ( 0xff, 0xfd, 0x01 ),
2250  .score = USB_SCORE_NORMAL,
2251  .probe = iphone_probe,
2252  .remove = iphone_remove,
2253 };
2254 
2255 /* Drag in objects via iphone_driver */
2256 REQUIRING_SYMBOL ( iphone_driver );
2257 
2258 /* Drag in RSA-with-SHA256 OID prefixes */
2259 REQUIRE_OBJECT ( rsa_sha256 );
Transport Layer Security Protocol.
static void ipair_close(struct ipair *ipair, int rc)
Shut down pairing client.
Definition: iphone.c:1255
A process.
Definition: process.h:17
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
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:1393
#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:768
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:206
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
#define iob_put(iobuf, len)
Definition: iobuf.h:120
#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:703
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:1982
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:1999
#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
uint32_t next
Next descriptor address.
Definition: myson.h:18
static void imux_rx_syn(struct imux *imux)
Receive pseudo-TCP SYN+ACK.
Definition: iphone.c:803
#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:1844
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:1827
static int ipair_tx(struct ipair *ipair, const char *fmt,...)
Transmit XML message.
Definition: iphone.c:1273
#define TCP_ACK
Definition: tcp.h:159
#define iob_push(iobuf, len)
Definition: iobuf.h:84
static void ipair_expired(struct retry_timer *timer, int over __unused)
Pairing transmission timer.
Definition: iphone.c:1809
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
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:752
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:212
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:923
static int ipair_rx_pair(struct ipair *ipair, char *msg)
Receive Pair message.
Definition: iphone.c:1616
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:1209
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:955
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition: x509.c:1310
static const char ipair_host_id[]
Arbitrary host ID used for pairing.
Definition: iphone.c:1228
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:1679
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:1703
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:129
#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:818
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:1317
static int icert_certs(struct icert *icert, struct asn1_cursor *key)
Construct certificates.
Definition: iphone.c:457
#define ECANCELED
Operation canceled.
Definition: errno.h:343
static void iphone_remove(struct usb_function *func)
Remove device.
Definition: iphone.c:2226
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:2141
static const uint8_t icert_name_ipxe_data[]
"iPXE" subject name
Definition: iphone.c:212
unsigned long tmp
Definition: linux_pci.h:63
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:1070
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:2128
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
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:73
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
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:2068
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:1049
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:658
#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:290
#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:572
#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:643
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:360
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:1772
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.
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:540
static struct net_device * netdev
Definition: gdbudp.c:52
struct usb_driver imux_driver __usb_driver
USB multiplexer driver.
Definition: iphone.c:1192
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:280
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:1113
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:1025
int meta(WINDOW *, bool)
static struct interface_descriptor ipair_xfer_desc
Pairing client interface descriptor.
Definition: iphone.c:1834
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:201
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition: asn1.c:890
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:1225
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:624
static void iphone_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition: iphone.c:1888
static int iphone_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: iphone.c:2111
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:155
#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:528
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:1972
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:1940
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:939
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:973
#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
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
static struct usb_endpoint_driver_operations iphone_in_operations
Bulk IN endpoint operations.
Definition: iphone.c:1929
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:1234
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:1421
#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:672
#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:1220
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:2050
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:67
static int ipair_tag(struct ipair *ipair, const char *msg, const char *tag, char **start, char **end)
Locate XML tag.
Definition: iphone.c:1359
#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:982
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:1652
uint8_t level
Log level.
Definition: iphone.h:85
static void imux_remove(struct usb_function *func)
Remove device.
Definition: iphone.c:1174
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:1444
static void ipair_free(struct refcnt *refcnt)
Free pairing client.
Definition: iphone.c:1242
#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
int pem_asn1(userptr_t data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from PEM data.
Definition: pem.c:105
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:48
#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:610
static struct usb_device_id imux_ids[]
USB multiplexer device IDs.
Definition: iphone.c:1183
struct usb_hub * hub
USB hub.
Definition: usb.h:814
static int ipair_tx_pair(struct ipair *ipair)
Transmit Pair message.
Definition: iphone.c:1527
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:946
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:700
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
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:131
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:876
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:459
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:1103
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:964
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:928
static int ipair_rx_pair_error(struct ipair *ipair, char *error)
Receive Pair message error.
Definition: iphone.c:1592
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
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key)
Definition: crypto.h:269
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:2094
struct usb_bus * bus
USB bus.
Definition: usb.h:844
#define IPHONE_GET_LINK
Get link status.
Definition: iphone.h:239
static int pubkey_sign(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, void *signature)
Definition: crypto.h:287
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.
uint32_t len
Length.
Definition: ena.h:14
Link up.
Definition: iphone.h:248
static int iphone_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: iphone.c:2155
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:1078
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:1745
static struct usb_device_id iphone_ids[]
iPhone device IDs
Definition: iphone.c:2237
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 @383 key
Sense key.
Definition: scsi.h:18
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:3799
static int imux_start_pair(struct imux *imux)
Open pairing client.
Definition: iphone.c:734
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:285
#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:33
static struct interface_operation imux_tcp_operations[]
Pseudo-TCP socket interface operations.
Definition: iphone.c:1063
static void iphone_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition: iphone.c:1962
#define ASN1_OID_SHA256WITHRSAENCRYPTION
ASN.1 OID for sha256WithRSAEncryption (1.2.840.113549.1.1.11)
Definition: asn1.h:149
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition: usbnet.c:54