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  vsnprintf ( msg, len, fmt, args );
1308  DBGC2 ( ipair, "IPAIR %p transmitting:\n%s\n", ipair, msg );
1309 
1310  /* Transmit message */
1311  if ( ( rc = xfer_deliver_iob ( &ipair->xfer,
1312  iob_disown ( iobuf ) ) ) != 0 )
1313  return rc;
1314 
1315  return 0;
1316 }
1317 
1318 /**
1319  * Receive XML message payload
1320  *
1321  * @v ipair Pairing client
1322  * @v msg Message payload
1323  * @v len Length of message
1324  * @ret rc Return status code
1325  */
1326 static int ipair_rx ( struct ipair *ipair, char *msg, size_t len ) {
1327  int ( * rx ) ( struct ipair *ipair, char *msg );
1328  int rc;
1329 
1330  /* Ignore empty messages */
1331  if ( ! len )
1332  return 0;
1333 
1334  /* Sanity check */
1335  if ( ( msg[ len - 1 ] != '\0' ) && ( msg[ len - 1 ] != '\n' ) ) {
1336  DBGC ( ipair, "IPAIR %p malformed XML:\n", ipair );
1337  DBGC_HDA ( ipair, 0, msg, len );
1338  return -EPROTO;
1339  }
1340 
1341  /* Add NUL terminator (potentially overwriting final newline) */
1342  msg[ len - 1 ] = '\0';
1343  DBGC2 ( ipair, "IPAIR %p received:\n%s\n\n", ipair, msg );
1344 
1345  /* Handle according to current state */
1346  rx = ipair->rx;
1347  if ( ! rx ) {
1348  DBGC ( ipair, "IPAIR %p unexpected XML:\n%s\n", ipair, msg );
1349  return -EPROTO;
1350  }
1351  ipair->rx = NULL;
1352  if ( ( rc = rx ( ipair, msg ) ) != 0 )
1353  return rc;
1354 
1355  return 0;
1356 }
1357 
1358 /**
1359  * Locate XML tag
1360  *
1361  * @v ipair Pairing client
1362  * @v msg XML message
1363  * @v tag Tag name
1364  * @ret start Start of tag content
1365  * @ret end End of tag content
1366  * @ret rc Return status code
1367  */
1368 static int ipair_tag ( struct ipair *ipair, const char *msg, const char *tag,
1369  char **start, char **end ) {
1370  char buf[ 2 /* "</" */ + strlen ( tag ) + 1 /* ">" */ + 1 /* NUL */ ];
1371 
1372  /* Locate opening tag */
1373  sprintf ( buf, "<%s>", tag );
1374  *start = strstr ( msg, buf );
1375  if ( ! *start )
1376  return -ENOENT;
1377  *start += strlen ( buf );
1378 
1379  /* Locate closing tag */
1380  sprintf ( buf, "</%s>", tag );
1381  *end = strstr ( *start, buf );
1382  if ( ! *end ) {
1383  DBGC ( ipair, "IPAIR %p missing closing tag %s in:\n%s\n",
1384  ipair, buf, msg );
1385  return -ENOENT;
1386  }
1387 
1388  return 0;
1389 }
1390 
1391 /**
1392  * Locate XML property list dictionary value
1393  *
1394  * @v ipair Pairing client
1395  * @v msg XML message
1396  * @v key Key name
1397  * @v type Key type
1398  * @ret start Start of value content
1399  * @ret end End of value content
1400  * @ret rc Return status code
1401  */
1402 static int ipair_key ( struct ipair *ipair, const char *msg, const char *key,
1403  const char *type, char **start, char **end ) {
1404  int rc;
1405 
1406  /* Iterate over keys */
1407  while ( 1 ) {
1408 
1409  /* Locate key */
1410  if ( ( rc = ipair_tag ( ipair, msg, "key", start,
1411  end ) ) != 0 )
1412  return rc;
1413  msg = *end;
1414 
1415  /* Check key name */
1416  if ( memcmp ( *start, key, ( *end - *start ) ) != 0 )
1417  continue;
1418 
1419  /* Locate value */
1420  return ipair_tag ( ipair, msg, type, start, end );
1421  }
1422 }
1423 
1424 /**
1425  * Transmit DevicePublicKey message
1426  *
1427  * @v ipair Pairing client
1428  * @ret rc Return status code
1429  */
1430 static int ipair_tx_pubkey ( struct ipair *ipair ) {
1431  int rc;
1432 
1433  /* Transmit message */
1434  if ( ( rc = ipair_tx ( ipair,
1435  "%s"
1436  "<string>GetValue</string>\n"
1437  "<key>Key</key>\n"
1438  "<string>DevicePublicKey</string>\n"
1439  "%s",
1440  ipair_prefix, ipair_suffix ) ) != 0 )
1441  return rc;
1442 
1443  return 0;
1444 }
1445 
1446 /**
1447  * Receive DevicePublicKey message
1448  *
1449  * @v ipair Pairing client
1450  * @v msg XML message
1451  * @ret rc Return status code
1452  */
1453 static int ipair_rx_pubkey ( struct ipair *ipair, char *msg ) {
1454  struct asn1_cursor *key;
1455  char *data;
1456  char *end;
1457  char *decoded;
1458  size_t max_len;
1459  int len;
1460  int next;
1461  int rc;
1462 
1463  /* Locate "Value" value */
1464  if ( ( rc = ipair_key ( ipair, msg, "Value", "data", &data,
1465  &end ) ) != 0 ) {
1466  DBGC ( ipair, "IPAIR %p unexpected public key message:\n%s\n",
1467  ipair, msg );
1468  goto err_tag;
1469  }
1470  *end = '\0';
1471 
1472  /* Decode outer layer of Base64 */
1474  decoded = malloc ( max_len );
1475  if ( ! decoded ) {
1476  rc = -ENOMEM;
1477  goto err_alloc;
1478  }
1479  len = base64_decode ( data, decoded, max_len );
1480  if ( len < 0 ) {
1481  rc = len;
1482  DBGC ( ipair, "IPAIR %p invalid outer public key:\n%s\n",
1483  ipair, data );
1484  goto err_decode;
1485  }
1486 
1487  /* Decode inner layer of Base64 */
1488  next = pem_asn1 ( virt_to_user ( decoded ), len, 0, &key );
1489  if ( next < 0 ) {
1490  rc = next;
1491  DBGC ( ipair, "IPAIR %p invalid inner public key:\n%s\n",
1492  ipair, decoded );
1493  goto err_asn1;
1494  }
1495  DBGC ( ipair, "IPAIR %p received public key\n", ipair );
1496  DBGC2_HDA ( ipair, 0, key->data, key->len );
1497 
1498  /* Construct certificates */
1499  if ( ( rc = icert_certs ( &ipair->icert, key ) ) != 0 )
1500  goto err_certs;
1501 
1502  /* Send session request or pair request as applicable */
1503  if ( ipair->flags & IPAIR_REQUEST ) {
1504  ipair->tx = ipair_tx_pair;
1505  ipair->rx = ipair_rx_pair;
1506  } else {
1509  }
1511 
1512  /* Free key */
1513  free ( key );
1514 
1515  /* Free intermediate Base64 */
1516  free ( decoded );
1517 
1518  return 0;
1519 
1520  err_certs:
1521  free ( key );
1522  err_asn1:
1523  err_decode:
1524  free ( decoded );
1525  err_alloc:
1526  err_tag:
1527  return rc;
1528 }
1529 
1530 /**
1531  * Transmit Pair message
1532  *
1533  * @v ipair Pairing client
1534  * @ret rc Return status code
1535  */
1536 static int ipair_tx_pair ( struct ipair *ipair ) {
1537  char *root;
1538  char *host;
1539  char *device;
1540  int rc;
1541 
1542  /* Construct doubly encoded certificates */
1543  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.root,
1544  &root ) ) != 0 )
1545  goto err_root;
1546  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.host,
1547  &host ) ) != 0 )
1548  goto err_host;
1549  if ( ( rc = icert_encode ( &ipair->icert, ipair->icert.device,
1550  &device ) ) != 0 )
1551  goto err_device;
1552 
1553  /* Transmit message */
1554  if ( ( rc = ipair_tx ( ipair,
1555  "%s"
1556  "<string>Pair</string>\n"
1557  "<key>PairRecord</key>\n"
1558  "<dict>\n"
1559  "<key>RootCertificate</key>\n"
1560  "<data>%s</data>\n"
1561  "<key>HostCertificate</key>\n"
1562  "<data>%s</data>\n"
1563  "<key>DeviceCertificate</key>\n"
1564  "<data>%s</data>\n"
1565  "<key>SystemBUID</key>\n"
1566  "<string>%s</string>\n"
1567  "<key>HostID</key>\n"
1568  "<string>%s</string>\n"
1569  "</dict>\n"
1570  "<key>ProtocolVersion</key>\n"
1571  "<string>2</string>\n"
1572  "<key>PairingOptions</key>\n"
1573  "<dict>\n"
1574  "<key>ExtendedPairingErrors</key>\n"
1575  "<true/>\n"
1576  "</dict>\n"
1577  "%s",
1578  ipair_prefix, root, host, device,
1580  ipair_suffix
1581  ) ) != 0 )
1582  goto err_tx;
1583 
1584  err_tx:
1585  free ( device );
1586  err_device:
1587  free ( host );
1588  err_host:
1589  free ( root );
1590  err_root:
1591  return rc;
1592 }
1593 
1594 /**
1595  * Receive Pair message error
1596  *
1597  * @v ipair Pairing client
1598  * @v error Pairing error
1599  * @ret rc Return status code
1600  */
1601 static int ipair_rx_pair_error ( struct ipair *ipair, char *error ) {
1602 
1603  /* Check for actual errors */
1604  if ( strcmp ( error, "PairingDialogResponsePending" ) != 0 ) {
1605  DBGC ( ipair, "IPAIR %p pairing error \"%s\"\n", ipair, error );
1606  return -EPERM;
1607  }
1608 
1609  /* Retransmit pairing request */
1610  ipair->tx = ipair_tx_pair;
1611  ipair->rx = ipair_rx_pair;
1613 
1614  DBGC ( ipair, "IPAIR %p waiting for pairing dialog\n", ipair );
1615  return 0;
1616 }
1617 
1618 /**
1619  * Receive Pair message
1620  *
1621  * @v ipair Pairing client
1622  * @v msg XML message
1623  * @ret rc Return status code
1624  */
1625 static int ipair_rx_pair ( struct ipair *ipair, char *msg ) {
1626  char *error;
1627  char *escrow;
1628  char *end;
1629  int rc;
1630 
1631  /* Check for pairing errors */
1632  if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1633  &end ) ) == 0 ) {
1634  *end = '\0';
1635  return ipair_rx_pair_error ( ipair, error );
1636  }
1637 
1638  /* Get EscrowBag */
1639  if ( ( rc = ipair_key ( ipair, msg, "EscrowBag", "data", &escrow,
1640  &end ) ) != 0 ) {
1641  DBGC ( ipair, "IPAIR %p unexpected pairing response:\n%s\n",
1642  ipair, msg );
1643  return rc;
1644  }
1645  DBGC ( ipair, "IPAIR %p pairing successful\n", ipair );
1646 
1647  /* Send session request */
1651 
1652  return 0;
1653 }
1654 
1655 /**
1656  * Transmit StartSession message
1657  *
1658  * @v ipair Pairing client
1659  * @ret rc Return status code
1660  */
1661 static int ipair_tx_session ( struct ipair *ipair ) {
1662  int rc;
1663 
1664  /* Transmit message */
1665  if ( ( rc = ipair_tx ( ipair,
1666  "%s"
1667  "<string>StartSession</string>\n"
1668  "<key>SystemBUID</key>\n"
1669  "<string>%s</string>\n"
1670  "<key>HostID</key>\n"
1671  "<string>%s</string>\n"
1672  "%s",
1675  ) ) != 0 )
1676  return rc;
1677 
1678  return 0;
1679 }
1680 
1681 /**
1682  * Receive StartSession message error
1683  *
1684  * @v ipair Pairing client
1685  * @v error Pairing error
1686  * @ret rc Return status code
1687  */
1688 static int ipair_rx_session_error ( struct ipair *ipair, char *error ) {
1689 
1690  /* Check for actual errors */
1691  if ( strcmp ( error, "InvalidHostID" ) != 0 ) {
1692  DBGC ( ipair, "IPAIR %p session error \"%s\"\n", ipair, error );
1693  return -EPERM;
1694  }
1695 
1696  /* Transmit pairing request */
1697  ipair->tx = ipair_tx_pair;
1698  ipair->rx = ipair_rx_pair;
1700 
1701  DBGC ( ipair, "IPAIR %p unknown host: requesting pairing\n", ipair );
1702  return 0;
1703 }
1704 
1705 /**
1706  * Receive StartSession message
1707  *
1708  * @v ipair Pairing client
1709  * @v msg XML message
1710  * @ret rc Return status code
1711  */
1712 static int ipair_rx_session ( struct ipair *ipair, char *msg ) {
1713  char *error;
1714  char *session;
1715  char *end;
1716  int rc;
1717 
1718  /* Check for session errors */
1719  if ( ( rc = ipair_key ( ipair, msg, "Error", "string", &error,
1720  &end ) ) == 0 ) {
1721  *end = '\0';
1722  return ipair_rx_session_error ( ipair, error );
1723  }
1724 
1725  /* Check for session ID */
1726  if ( ( rc = ipair_key ( ipair, msg, "SessionID", "string", &session,
1727  &end ) ) != 0 ) {
1728  DBGC ( ipair, "IPAIR %p unexpected session response:\n%s\n",
1729  ipair, msg );
1730  return rc;
1731  }
1732  *end = '\0';
1733  DBGC ( ipair, "IPAIR %p starting session \"%s\"\n", ipair, session );
1734 
1735  /* Start TLS */
1736  if ( ( rc = add_tls ( &ipair->xfer, "iPhone", &icert_root,
1737  ipair->icert.key ) ) != 0 ) {
1738  DBGC ( ipair, "IPAIR %p could not start TLS: %s\n",
1739  ipair, strerror ( rc ) );
1740  return rc;
1741  }
1742 
1743  /* Record that TLS has been started */
1744  ipair->flags |= IPAIR_TLS;
1745 
1746  return 0;
1747 }
1748 
1749 /**
1750  * Handle window change notification
1751  *
1752  * @v ipair Pairing client
1753  */
1754 static void ipair_window_changed ( struct ipair *ipair ) {
1755 
1756  /* Report pairing as complete once TLS session has been established */
1757  if ( ( ipair->flags & IPAIR_TLS ) && xfer_window ( &ipair->xfer ) ) {
1758 
1759  /* Sanity checks */
1762  assert ( ! x509_is_valid ( ipair->icert.root, NULL ) );
1763  assert ( ! x509_is_valid ( ipair->icert.host, NULL ) );
1764  assert ( ! x509_is_valid ( ipair->icert.device, NULL ) );
1765 
1766  /* Report pairing as complete */
1767  DBGC ( ipair, "IPAIR %p established TLS session\n", ipair );
1768  ipair_close ( ipair, 0 );
1769  return;
1770  }
1771 }
1772 
1773 /**
1774  * Handle received data
1775  *
1776  * @v ipair Pairing client
1777  * @v iobuf I/O buffer
1778  * @v meta Data transfer metadata
1779  * @ret rc Return status code
1780  */
1781 static int ipair_deliver ( struct ipair *ipair, struct io_buffer *iobuf,
1782  struct xfer_metadata *meta __unused ) {
1783  struct ipair_header *hdr;
1784  int rc;
1785 
1786  /* Strip header (which may appear in a separate packet) */
1787  if ( ( ! ( ipair->flags & IPAIR_RX_LEN ) ) &&
1788  ( iob_len ( iobuf ) >= sizeof ( *hdr ) ) ) {
1789  iob_pull ( iobuf, sizeof ( *hdr ) );
1790  ipair->flags |= IPAIR_RX_LEN;
1791  }
1792 
1793  /* Clear received header flag if we have a message */
1794  if ( iob_len ( iobuf ) )
1795  ipair->flags &= ~IPAIR_RX_LEN;
1796 
1797  /* Receive message */
1798  if ( ( rc = ipair_rx ( ipair, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
1799  goto error;
1800 
1801  /* Free I/O buffer */
1802  free_iob ( iobuf );
1803 
1804  return 0;
1805 
1806  error:
1807  ipair_close ( ipair, rc );
1808  free_iob ( iobuf );
1809  return rc;
1810 }
1811 
1812 /**
1813  * Pairing transmission timer
1814  *
1815  * @v timer Retransmission timer
1816  * @v over Failure indicator
1817  */
1818 static void ipair_expired ( struct retry_timer *timer, int over __unused ) {
1819  struct ipair *ipair = container_of ( timer, struct ipair, timer );
1820  int ( * tx ) ( struct ipair *ipair );
1821  int rc;
1822 
1823  /* Sanity check */
1824  tx = ipair->tx;
1825  assert ( tx != NULL );
1826 
1827  /* Clear pending transmission */
1828  ipair->tx = NULL;
1829 
1830  /* Transmit data, if applicable */
1831  if ( ( rc = tx ( ipair ) ) != 0 )
1832  ipair_close ( ipair, rc );
1833 }
1834 
1835 /** Pairing client interface operations */
1837  INTF_OP ( xfer_deliver, struct ipair *, ipair_deliver ),
1839  INTF_OP ( intf_close, struct ipair *, ipair_close ),
1840 };
1841 
1842 /** Pairing client interface descriptor */
1844  INTF_DESC ( struct ipair, xfer, ipair_xfer_operations );
1845 
1846 /**
1847  * Create a pairing client
1848  *
1849  * @v xfer Data transfer interface
1850  * @v flags Initial state flags
1851  * @ret rc Return status code
1852  */
1853 static int ipair_create ( struct interface *xfer, unsigned int flags ) {
1854  struct ipair *ipair;
1855  int rc;
1856 
1857  /* Allocate and initialise structure */
1858  ipair = zalloc ( sizeof ( *ipair ) );
1859  if ( ! ipair ) {
1860  rc = -ENOMEM;
1861  goto err_alloc;
1862  }
1865  timer_init ( &ipair->timer, ipair_expired, &ipair->refcnt );
1868  ipair->flags = flags;
1869 
1870  /* Schedule initial transmission */
1872 
1873  /* Attach to parent interface, mortalise self, and return */
1874  intf_plug_plug ( &ipair->xfer, xfer );
1875  ref_put ( &ipair->refcnt );
1876  return 0;
1877 
1878  ref_put ( &ipair->refcnt );
1879  err_alloc:
1880  return rc;
1881 }
1882 
1883 /******************************************************************************
1884  *
1885  * iPhone USB networking
1886  *
1887  ******************************************************************************
1888  */
1889 
1890 /**
1891  * Complete bulk IN transfer
1892  *
1893  * @v ep USB endpoint
1894  * @v iobuf I/O buffer
1895  * @v rc Completion status code
1896  */
1897 static void iphone_in_complete ( struct usb_endpoint *ep,
1898  struct io_buffer *iobuf, int rc ) {
1899  struct iphone *iphone = container_of ( ep, struct iphone, usbnet.in );
1900  struct net_device *netdev = iphone->netdev;
1901 
1902  /* Profile receive completions */
1903  profile_start ( &iphone_in_profiler );
1904 
1905  /* Ignore packets cancelled when the endpoint closes */
1906  if ( ! ep->open )
1907  goto ignore;
1908 
1909  /* Record USB errors against the network device */
1910  if ( rc != 0 ) {
1911  DBGC ( iphone, "IPHONE %p bulk IN failed: %s\n",
1912  iphone, strerror ( rc ) );
1913  goto error;
1914  }
1915 
1916  /* Strip padding */
1917  if ( iob_len ( iobuf ) < IPHONE_IN_PAD ) {
1918  DBGC ( iphone, "IPHONE %p malformed bulk IN:\n", iphone );
1919  DBGC_HDA ( iphone, 0, iobuf->data, iob_len ( iobuf ) );
1920  rc = -EINVAL;
1921  goto error;
1922  }
1923  iob_pull ( iobuf, IPHONE_IN_PAD );
1924 
1925  /* Hand off to network stack */
1926  netdev_rx ( netdev, iob_disown ( iobuf ) );
1927 
1928  profile_stop ( &iphone_in_profiler );
1929  return;
1930 
1931  error:
1932  netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
1933  ignore:
1934  free_iob ( iobuf );
1935 }
1936 
1937 /** Bulk IN endpoint operations */
1940 };
1941 
1942 /**
1943  * Transmit packet
1944  *
1945  * @v iphone iPhone device
1946  * @v iobuf I/O buffer
1947  * @ret rc Return status code
1948  */
1949 static int iphone_out_transmit ( struct iphone *iphone,
1950  struct io_buffer *iobuf ) {
1951  int rc;
1952 
1953  /* Profile transmissions */
1954  profile_start ( &iphone_out_profiler );
1955 
1956  /* Enqueue I/O buffer */
1957  if ( ( rc = usb_stream ( &iphone->usbnet.out, iobuf, 1 ) ) != 0 )
1958  return rc;
1959 
1960  profile_stop ( &iphone_out_profiler );
1961  return 0;
1962 }
1963 
1964 /**
1965  * Complete bulk OUT transfer
1966  *
1967  * @v ep USB endpoint
1968  * @v iobuf I/O buffer
1969  * @v rc Completion status code
1970  */
1971 static void iphone_out_complete ( struct usb_endpoint *ep,
1972  struct io_buffer *iobuf, int rc ) {
1973  struct iphone *iphone = container_of ( ep, struct iphone, usbnet.out );
1974  struct net_device *netdev = iphone->netdev;
1975 
1976  /* Report TX completion */
1977  netdev_tx_complete_err ( netdev, iobuf, rc );
1978 }
1979 
1980 /** Bulk OUT endpoint operations */
1983 };
1984 
1985 /**
1986  * Check pairing status
1987  *
1988  * @v iphone iPhone device
1989  * @ret rc Return status code
1990  */
1991 static int iphone_check_pair ( struct iphone *iphone ) {
1992  struct imux *imux;
1993 
1994  /* Find corresponding USB multiplexer */
1995  list_for_each_entry ( imux, &imuxes, list ) {
1996  if ( imux->usb == iphone->usb )
1997  return imux->rc;
1998  }
1999 
2000  return -EPIPE_NO_MUX;
2001 }
2002 
2003 /**
2004  * Check link status
2005  *
2006  * @v netdev Network device
2007  */
2008 static void iphone_check_link ( struct net_device *netdev ) {
2009  struct iphone *iphone = netdev->priv;
2010  struct usb_device *usb = iphone->usb;
2011  uint8_t status;
2012  int rc;
2013 
2014  /* Check pairing status */
2015  if ( ( rc = iphone_check_pair ( iphone ) ) != 0 )
2016  goto err_pair;
2017 
2018  /* Get link status */
2019  if ( ( rc = usb_control ( usb, IPHONE_GET_LINK, 0, 0, &status,
2020  sizeof ( status ) ) ) != 0 ) {
2021  DBGC ( iphone, "IPHONE %p could not get link status: %s\n",
2022  iphone, strerror ( rc ) );
2023  goto err_control;
2024  }
2025 
2026  /* Check link status */
2027  if ( status != IPHONE_LINK_UP ) {
2028  rc = -ENOTCONN_STATUS ( status );
2029  goto err_status;
2030  }
2031 
2032  /* Success */
2033  rc = 0;
2034 
2035  err_status:
2036  err_control:
2037  err_pair:
2038  /* Report link status. Since we have to check the link
2039  * periodically (due to an absence of an interrupt endpoint),
2040  * do this only if the link status has actually changed.
2041  */
2042  if ( rc != netdev->link_rc ) {
2043  if ( rc == 0 ) {
2044  DBGC ( iphone, "IPHONE %p link up\n", iphone );
2045  } else {
2046  DBGC ( iphone, "IPHONE %p link down: %s\n",
2047  iphone, strerror ( rc ) );
2048  }
2049  netdev_link_err ( netdev, rc );
2050  }
2051 }
2052 
2053 /**
2054  * Periodically update link status
2055  *
2056  * @v timer Link status timer
2057  * @v over Failure indicator
2058  */
2059 static void iphone_expired ( struct retry_timer *timer, int over __unused ) {
2060  struct iphone *iphone = container_of ( timer, struct iphone, timer );
2061  struct net_device *netdev = iphone->netdev;
2062 
2063  /* Check link status */
2065 
2066  /* Restart timer, if device is open */
2067  if ( netdev_is_open ( netdev ) )
2069 }
2070 
2071 /**
2072  * Open network device
2073  *
2074  * @v netdev Network device
2075  * @ret rc Return status code
2076  */
2077 static int iphone_open ( struct net_device *netdev ) {
2078  struct iphone *iphone = netdev->priv;
2079  int rc;
2080 
2081  /* Open USB network device */
2082  if ( ( rc = usbnet_open ( &iphone->usbnet ) ) != 0 ) {
2083  DBGC ( iphone, "IPHONE %p could not open: %s\n",
2084  iphone, strerror ( rc ) );
2085  goto err_open;
2086  }
2087 
2088  /* Start the link status check timer */
2090 
2091  return 0;
2092 
2093  usbnet_close ( &iphone->usbnet );
2094  err_open:
2095  return rc;
2096 }
2097 
2098 /**
2099  * Close network device
2100  *
2101  * @v netdev Network device
2102  */
2103 static void iphone_close ( struct net_device *netdev ) {
2104  struct iphone *iphone = netdev->priv;
2105 
2106  /* Stop the link status check timer */
2107  stop_timer ( &iphone->timer );
2108 
2109  /* Close USB network device */
2110  usbnet_close ( &iphone->usbnet );
2111 }
2112 
2113 /**
2114  * Transmit packet
2115  *
2116  * @v netdev Network device
2117  * @v iobuf I/O buffer
2118  * @ret rc Return status code
2119  */
2120 static int iphone_transmit ( struct net_device *netdev,
2121  struct io_buffer *iobuf ) {
2122  struct iphone *iphone = netdev->priv;
2123  int rc;
2124 
2125  /* Transmit packet */
2126  if ( ( rc = iphone_out_transmit ( iphone, iobuf ) ) != 0 )
2127  return rc;
2128 
2129  return 0;
2130 }
2131 
2132 /**
2133  * Poll for completed and received packets
2134  *
2135  * @v netdev Network device
2136  */
2137 static void iphone_poll ( struct net_device *netdev ) {
2138  struct iphone *iphone = netdev->priv;
2139  int rc;
2140 
2141  /* Poll USB bus */
2142  usb_poll ( iphone->bus );
2143 
2144  /* Refill endpoints */
2145  if ( ( rc = usbnet_refill ( &iphone->usbnet ) ) != 0 )
2146  netdev_rx_err ( netdev, NULL, rc );
2147 }
2148 
2149 /** iPhone network device operations */
2151  .open = iphone_open,
2152  .close = iphone_close,
2153  .transmit = iphone_transmit,
2154  .poll = iphone_poll,
2155 };
2156 
2157 /**
2158  * Probe device
2159  *
2160  * @v func USB function
2161  * @v config Configuration descriptor
2162  * @ret rc Return status code
2163  */
2164 static int iphone_probe ( struct usb_function *func,
2165  struct usb_configuration_descriptor *config ) {
2166  struct usb_device *usb = func->usb;
2167  struct net_device *netdev;
2168  struct iphone *iphone;
2169  int rc;
2170 
2171  /* Allocate and initialise structure */
2172  netdev = alloc_etherdev ( sizeof ( *iphone ) );
2173  if ( ! netdev ) {
2174  rc = -ENOMEM;
2175  goto err_alloc;
2176  }
2178  netdev->dev = &func->dev;
2179  iphone = netdev->priv;
2180  memset ( iphone, 0, sizeof ( *iphone ) );
2181  iphone->usb = usb;
2182  iphone->bus = usb->port->hub->bus;
2183  iphone->netdev = netdev;
2188  timer_init ( &iphone->timer, iphone_expired, &netdev->refcnt );
2189  DBGC ( iphone, "IPHONE %p on %s\n", iphone, func->name );
2190 
2191  /* Describe USB network device */
2192  if ( ( rc = usbnet_describe ( &iphone->usbnet, config ) ) != 0 ) {
2193  DBGC ( iphone, "IPHONE %p could not describe: %s\n",
2194  iphone, strerror ( rc ) );
2195  goto err_describe;
2196  }
2197 
2198  /* Fetch MAC address */
2199  if ( ( rc = usb_control ( usb, IPHONE_GET_MAC, 0, 0, netdev->hw_addr,
2200  ETH_ALEN ) ) != 0 ) {
2201  DBGC ( iphone, "IPHONE %p could not fetch MAC address: %s\n",
2202  iphone, strerror ( rc ) );
2203  goto err_fetch_mac;
2204  }
2205 
2206  /* Register network device */
2207  if ( ( rc = register_netdev ( netdev ) ) != 0 )
2208  goto err_register;
2209 
2210  /* Set initial link status */
2212 
2213  /* Add to list of iPhone network devices */
2214  list_add ( &iphone->list, &iphones );
2215 
2216  usb_func_set_drvdata ( func, iphone );
2217  return 0;
2218 
2219  list_del ( &iphone->list );
2221  err_register:
2222  err_fetch_mac:
2223  err_describe:
2224  netdev_nullify ( netdev );
2225  netdev_put ( netdev );
2226  err_alloc:
2227  return rc;
2228 }
2229 
2230 /**
2231  * Remove device
2232  *
2233  * @v func USB function
2234  */
2235 static void iphone_remove ( struct usb_function *func ) {
2236  struct iphone *iphone = usb_func_get_drvdata ( func );
2237  struct net_device *netdev = iphone->netdev;
2238 
2239  list_del ( &iphone->list );
2241  netdev_nullify ( netdev );
2242  netdev_put ( netdev );
2243 }
2244 
2245 /** iPhone device IDs */
2246 static struct usb_device_id iphone_ids[] = {
2247  {
2248  .name = "iphone",
2249  .vendor = 0x05ac,
2250  .product = USB_ANY_ID,
2251  },
2252 };
2253 
2254 /** iPhone driver */
2255 struct usb_driver iphone_driver __usb_driver = {
2256  .ids = iphone_ids,
2257  .id_count = ( sizeof ( iphone_ids ) / sizeof ( iphone_ids[0] ) ),
2258  .class = USB_CLASS_ID ( 0xff, 0xfd, 0x01 ),
2259  .score = USB_SCORE_NORMAL,
2260  .probe = iphone_probe,
2261  .remove = iphone_remove,
2262 };
2263 
2264 /* Drag in objects via iphone_driver */
2265 REQUIRING_SYMBOL ( iphone_driver );
2266 
2267 /* Drag in RSA-with-SHA256 OID prefixes */
2268 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:1402
#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
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:177
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
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:342
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:542
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:36
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:254
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:1991
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:2008
#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
static void size_t size_t max_len
Definition: entropy.h:153
#define SHA256_CTX_SIZE
SHA-256 context size.
Definition: sha256.h:71
struct refcnt refcnt
Reference count.
Definition: x509.h:346
#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:1853
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:1836
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:1818
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 void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
static const uint8_t icert_public_a [] __unused
Public key(s) used for pairing.
Definition: iphone.c:237
uint8_t type
Type.
Definition: ena.h:16
#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:775
static int ipair_rx_pair(struct ipair *ipair, char *msg)
Receive Pair message.
Definition: iphone.c:1625
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:157
#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:1688
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:1712
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
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define htonl(value)
Definition: byteswap.h:133
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
#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:1326
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:2235
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:2150
static const uint8_t icert_name_ipxe_data[]
"iPXE" subject name
Definition: iphone.c:212
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:2137
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:510
struct x509_certificate * host
Host certificate.
Definition: iphone.h:36
static size_t pubkey_max_len(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:226
#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:2077
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:664
#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:243
#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:567
#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:300
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:1781
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:420
#define DBGC_HDA(...)
Definition: compiler.h:506
PEM-encoded ASN.1 data.
struct digest_algorithm * digest
Fingerprint digest algorithm.
Definition: x509.h:348
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:233
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:899
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:1843
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition: asn1.c:742
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:185
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:1897
static int iphone_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: iphone.c:2120
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:722
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
uint8_t * tmp
Definition: entropy.h:156
#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:163
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:193
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:523
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:1981
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:1949
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:825
#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:1938
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:1430
#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:504
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:2059
An X.509 root certificate list.
Definition: x509.h:344
#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:1368
#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:426
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:1661
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
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)
static int ipair_rx_pubkey(struct ipair *ipair, char *msg)
Receive DevicePublicKey message.
Definition: iphone.c:1453
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:247
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 int pubkey_sign(struct pubkey_algorithm *pubkey, void *ctx, struct digest_algorithm *digest, const void *value, void *signature)
Definition: crypto.h:241
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:1536
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:798
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:615
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:16
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
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
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:254
#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:386
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
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#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:1601
struct asn1_cursor raw
Raw certificate.
Definition: x509.h:200
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:190
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:2103
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:2164
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:362
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:94
#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:1754
static struct usb_device_id iphone_ids[]
iPhone device IDs
Definition: iphone.c:2246
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 @376 key
Sense key.
Definition: scsi.h:18
An iPhone pairing certificate set.
Definition: iphone.h:30
static void icert_free(struct icert *icert)
Free pairing certificates.
Definition: iphone.c:330
struct retry_timer timer
Pairing timer.
Definition: iphone.h:189
int add_tls(struct interface *xfer, const char *name, struct x509_root *root, struct private_key *key)
Add TLS on an interface.
Definition: tls.c:3157
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:238
#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
static int pubkey_init(struct pubkey_algorithm *pubkey, void *ctx, const void *key, size_t key_len)
Definition: crypto.h:221
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:1971
#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