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