/*
 * lockdown-cu.c
 * com.apple.mobile.lockdownd service CU additions
 *
 * Copyright (c) 2021 Nikias Bassen, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <stdlib.h>
#define _GNU_SOURCE 1
#define __USE_GNU 1
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <plist/plist.h>

#include "idevice.h"
#include "lockdown.h"
#include "common/debug.h"

#ifdef HAVE_WIRELESS_PAIRING

#include <libimobiledevice-glue/utils.h>
#include <libimobiledevice-glue/socket.h>
#include <libimobiledevice-glue/opack.h>
#include <libimobiledevice-glue/tlv.h>

#if defined(HAVE_OPENSSL)
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2030200fL)
#include <openssl/chacha.h>
#include <openssl/poly1305.h>
#endif
#elif defined(HAVE_GCRYPT)
#include <gcrypt.h>
#elif defined(HAVE_MBEDTLS)
#include <mbedtls/md.h>
#include <mbedtls/chachapoly.h>
#endif

#ifdef __APPLE__
#include <sys/sysctl.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <CoreFoundation/CoreFoundation.h>
#endif

#include "property_list_service.h"
#include "common/userpref.h"

#include "endianness.h"

#include "srp.h"
#include "ed25519.h"

/* {{{ SRP6a parameters */
static const unsigned char kSRPModulus3072[384] = {
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34,
	0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
	0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
	0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37,
	0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
	0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
	0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6,
	0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
	0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,
	0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb,
	0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
	0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46, 0x2e, 0x36, 0xce, 0x3b,
	0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03, 0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f,
	0xb5, 0xc5, 0x5d, 0xf0, 0x6f, 0x4c, 0x52, 0xc9, 0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
	0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18, 0x98, 0xfa, 0x05, 0x10,
	0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xaa, 0xc4, 0x2d, 0xad, 0x33, 0x17, 0x0d, 0x04, 0x50, 0x7a, 0x33,
	0xa8, 0x55, 0x21, 0xab, 0xdf, 0x1c, 0xba, 0x64, 0xec, 0xfb, 0x85, 0x04, 0x58, 0xdb, 0xef, 0x0a,
	0x8a, 0xea, 0x71, 0x57, 0x5d, 0x06, 0x0c, 0x7d, 0xb3, 0x97, 0x0f, 0x85, 0xa6, 0xe1, 0xe4, 0xc7,
	0xab, 0xf5, 0xae, 0x8c, 0xdb, 0x09, 0x33, 0xd7, 0x1e, 0x8c, 0x94, 0xe0, 0x4a, 0x25, 0x61, 0x9d,
	0xce, 0xe3, 0xd2, 0x26, 0x1a, 0xd2, 0xee, 0x6b, 0xf1, 0x2f, 0xfa, 0x06, 0xd9, 0x8a, 0x08, 0x64,
	0xd8, 0x76, 0x02, 0x73, 0x3e, 0xc8, 0x6a, 0x64, 0x52, 0x1f, 0x2b, 0x18, 0x17, 0x7b, 0x20, 0x0c,
	0xbb, 0xe1, 0x17, 0x57, 0x7a, 0x61, 0x5d, 0x6c, 0x77, 0x09, 0x88, 0xc0, 0xba, 0xd9, 0x46, 0xe2,
	0x08, 0xe2, 0x4f, 0xa0, 0x74, 0xe5, 0xab, 0x31, 0x43, 0xdb, 0x5b, 0xfc, 0xe0, 0xfd, 0x10, 0x8e,
	0x4b, 0x82, 0xd1, 0x20, 0xa9, 0x3a, 0xd2, 0xca, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};

static const unsigned char kSRPGenerator5 = 5;
/* }}} */

/* {{{ HKDF */
#if defined(HAVE_OPENSSL)
#define MD_ALGO_SHA512 EVP_sha512()
typedef const EVP_MD* MD_ALGO_TYPE_T;
#define MD_ALGO_DIGEST_SIZE EVP_MD_size
#define MD_MAX_DIGEST_SIZE EVP_MAX_MD_SIZE

#elif defined(HAVE_GCRYPT)
#define MD_ALGO_SHA512 GCRY_MD_SHA512
typedef int MD_ALGO_TYPE_T;
#define MD_ALGO_DIGEST_SIZE gcry_md_get_algo_dlen
#define MD_MAX_DIGEST_SIZE 64

static void HMAC(MD_ALGO_TYPE_T md, unsigned char* key, unsigned int key_len, unsigned char* data, unsigned int data_len, unsigned char* out, unsigned int* out_len)
{
	gcry_md_hd_t hd;
	if (gcry_md_open(&hd, md, GCRY_MD_FLAG_HMAC)) {
		debug_info("gcry_md_open() failed");
		return;
	}
	if (gcry_md_setkey(hd, key, key_len)) {
		gcry_md_close (hd);
		debug_info("gcry_md_setkey() failed");
		return;
	}
	gcry_md_write(hd, data, data_len);

	unsigned char* digest = gcry_md_read(hd, md);
	if (!digest) {
		gcry_md_close(hd);
		debug_info("gcry_md_read() failed");
		return;
	}

	*out_len = gcry_md_get_algo_dlen(md);
	memcpy(out, digest, *out_len);
	gcry_md_close(hd);
}
#elif defined(HAVE_MBEDTLS)
#define MD_ALGO_SHA512 MBEDTLS_MD_SHA512
typedef mbedtls_md_type_t MD_ALGO_TYPE_T;
#define MD_ALGO_DIGEST_SIZE(x) mbedtls_md_get_size(mbedtls_md_info_from_type(x))
#define MD_MAX_DIGEST_SIZE MBEDTLS_MD_MAX_SIZE

static void HMAC(MD_ALGO_TYPE_T md, unsigned char* key, unsigned int key_len, unsigned char* data, unsigned int data_len, unsigned char* out, unsigned int* out_len)
{
	mbedtls_md_context_t mdctx;
	mbedtls_md_init(&mdctx);
	int mr = mbedtls_md_setup(&mdctx, mbedtls_md_info_from_type(md), 1);
	if (mr != 0) {
		debug_info("mbedtls_md_setup() failed: %d", mr);
		return;
	}

	mr = mbedtls_md_hmac_starts(&mdctx, key, key_len);
	if (mr != 0) {
		mbedtls_md_free(&mdctx);
		debug_info("mbedtls_md_hmac_starts() failed: %d", mr);
		return;
	}

	mbedtls_md_hmac_update(&mdctx, data, data_len);

	mr = mbedtls_md_hmac_finish(&mdctx, out);
	if (mr == 0) {
		*out_len = mbedtls_md_get_size(mbedtls_md_info_from_type(md));
	} else {
		debug_info("mbedtls_md_hmac_finish() failed: %d", mr);
	}
	mbedtls_md_free(&mdctx);
}
#endif

static void hkdf_md_extract(MD_ALGO_TYPE_T md, unsigned char* salt, unsigned int salt_len, unsigned char* input_key_material, unsigned int input_key_material_len, unsigned char* out, unsigned int* out_len)
{
	unsigned char empty_salt[MD_MAX_DIGEST_SIZE];
	if (!md || !out || !out_len || !*out_len) return;
	if (salt_len == 0) {
		salt_len = MD_ALGO_DIGEST_SIZE(md);
		salt = (unsigned char*)empty_salt;
	}
	HMAC(md, salt, salt_len, input_key_material, input_key_material_len, out, out_len);
}

static void hkdf_md_expand(MD_ALGO_TYPE_T md, unsigned char* prk, unsigned int prk_len, unsigned char* info, unsigned int info_len, unsigned char* out, unsigned int* out_len)
{
	if (!md || !out || !out_len || !*out_len) return;
	unsigned int md_size = MD_ALGO_DIGEST_SIZE(md);
	if (*out_len > 255 * md_size) {
		*out_len = 0;
		return;
	}
	int blocks_needed = (*out_len) / md_size;
	if (((*out_len) % md_size) != 0) blocks_needed++;
	unsigned int okm_len = 0;
	unsigned char okm_block[MD_MAX_DIGEST_SIZE];
	unsigned int okm_block_len = 0;
	int i;
	for (i = 0; i < blocks_needed; i++) {
		unsigned int output_block_len = okm_block_len + info_len + 1;
		unsigned char* output_block = malloc(output_block_len);
		if (okm_block_len > 0) {
			memcpy(output_block, okm_block, okm_block_len);
		}
		memcpy(output_block + okm_block_len, info, info_len);
		output_block[okm_block_len + info_len] = (uint8_t)(i+1);

		HMAC(md, prk, prk_len, output_block, output_block_len, okm_block, &okm_block_len);
		if (okm_len < *out_len) {
			memcpy(out + okm_len, okm_block, (okm_len + okm_block_len > *out_len) ? *out_len - okm_len : okm_block_len);
		}
		okm_len += okm_block_len;
		free(output_block);
	}
}

static void hkdf_md(MD_ALGO_TYPE_T md, unsigned char* salt, unsigned int salt_len, unsigned char* info, unsigned int info_len, unsigned char* initial_key_material, unsigned int initial_key_material_size, unsigned char* out, unsigned int *out_len)
{
	if (!md || !initial_key_material || !out || !out_len || !*out_len) return;

	unsigned char prk[MD_MAX_DIGEST_SIZE];
	unsigned int prk_len = MD_ALGO_DIGEST_SIZE(md);

	hkdf_md_extract(md, salt, salt_len, initial_key_material, initial_key_material_size, prk, &prk_len);
	if (prk_len > 0) {
		hkdf_md_expand(md, prk, prk_len, info, info_len, out, out_len);
	} else {
		*out_len = 0;
	}
}
/* }}} */

/* {{{ chacha20 poly1305 encryption/decryption */
#if defined(HAVE_OPENSSL) && defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2030200fL)
/* {{{ From: OpenBSD's e_chacha20poly1305.c */
/*
 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
 * Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
static void
poly1305_update_with_length(poly1305_state *poly1305,
    const unsigned char *data, size_t data_len)
{
	size_t j = data_len;
	unsigned char length_bytes[8];
	unsigned i;

	for (i = 0; i < sizeof(length_bytes); i++) {
		length_bytes[i] = j;
		j >>= 8;
	}

	if (data != NULL)
		CRYPTO_poly1305_update(poly1305, data, data_len);
	CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}

static void
poly1305_update_with_pad16(poly1305_state *poly1305,
    const unsigned char *data, size_t data_len)
{
	static const unsigned char zero_pad16[16];
	size_t pad_len;

	CRYPTO_poly1305_update(poly1305, data, data_len);

	/* pad16() is defined in RFC 7539 2.8.1. */
	if ((pad_len = data_len % 16) == 0)
		return;

	CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);
}
/* }}} */
#endif

static void chacha20_poly1305_encrypt_96(unsigned char* key, unsigned char* nonce, unsigned char* ad, size_t ad_len, unsigned char* in, size_t in_len, unsigned char* out, size_t* out_len)
{
#if defined(HAVE_OPENSSL)
#if defined(LIBRESSL_VERSION_NUMBER)
#if (LIBRESSL_VERSION_NUMBER >= 0x2040000fL)
	const EVP_AEAD *aead = EVP_aead_chacha20_poly1305();
	EVP_AEAD_CTX ctx;
	EVP_AEAD_CTX_init(&ctx, aead, key, EVP_AEAD_key_length(aead), EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
	EVP_AEAD_CTX_seal(&ctx, out, out_len, *out_len, nonce, 12, in, in_len, ad, ad_len);
#else
	unsigned char poly1305_key[32];
	poly1305_state poly1305;
	uint64_t ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | nonce[2] << 16 | nonce[3] << 24) << 32;
	const unsigned char* iv = nonce + 4;

	memset(poly1305_key, 0, sizeof(poly1305_key));
	CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key, iv, ctr);

	CRYPTO_poly1305_init(&poly1305, poly1305_key);
	poly1305_update_with_pad16(&poly1305, ad, ad_len);
	CRYPTO_chacha_20(out, in, in_len, key, iv, ctr + 1);
	poly1305_update_with_pad16(&poly1305, out, in_len);
	poly1305_update_with_length(&poly1305, NULL, ad_len);
	poly1305_update_with_length(&poly1305, NULL, in_len);

	CRYPTO_poly1305_finish(&poly1305, out + in_len);

	*out_len = in_len + 16;
#endif
#elif defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
	int outl = 0;
	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
	EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce);
	EVP_EncryptUpdate(ctx, out, &outl, in, in_len);
	*out_len = outl;
	outl = 0;
	EVP_EncryptFinal_ex(ctx, out + *out_len, &outl);
	*out_len += outl;
	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, out + *out_len);
	EVP_CIPHER_CTX_free(ctx);
	*out_len += 16;
#else
#error Please use a newer version of OpenSSL (>= 1.1.0)
#endif
#elif defined(HAVE_GCRYPT)
#if defined(GCRYPT_VERSION_NUMBER) && (GCRYPT_VERSION_NUMBER >= 0x010700)
	gcry_cipher_hd_t hd;
	if (gcry_cipher_open(&hd, GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_POLY1305, 0)) {
		debug_info("gcry_cipher_open() failed");
		return;
	}
	gcry_cipher_setkey(hd, key, 32);
	gcry_cipher_setiv(hd, nonce, 12);
	gcry_cipher_authenticate(hd, ad, ad_len);
	*out_len = in_len + 16;
	if (gcry_cipher_encrypt(hd, out, *out_len, in, in_len)) {
		*out_len = 0;
	}
	gcry_cipher_gettag(hd, out+in_len, 16);
	gcry_cipher_close(hd);
#else
#error Please use a newer version of libgcrypt (>= 1.7.0)
#endif
#elif defined (HAVE_MBEDTLS)
	mbedtls_chachapoly_context ctx;
	mbedtls_chachapoly_init(&ctx);
	mbedtls_chachapoly_setkey(&ctx, key);
	if (mbedtls_chachapoly_encrypt_and_tag(&ctx, in_len, nonce, ad, ad_len, in, out, out+in_len) != 0) {
		*out_len = 0;
	}
	mbedtls_chachapoly_free(&ctx);
#else
#error chacha20_poly1305_encrypt_96 is not implemented
#endif
}

static void chacha20_poly1305_encrypt_64(unsigned char* key, unsigned char* nonce, unsigned char* ad, size_t ad_len, unsigned char* in, size_t in_len, unsigned char* out, size_t* out_len)
{
	unsigned char _nonce[12];
	*(uint32_t*)(&_nonce[0]) = 0;
	memcpy(&_nonce[4], nonce, 8);
	chacha20_poly1305_encrypt_96(key, _nonce, ad, ad_len, in, in_len, out, out_len);
}

static void chacha20_poly1305_decrypt_96(unsigned char* key, unsigned char* nonce, unsigned char* ad, size_t ad_len, unsigned char* in, size_t in_len, unsigned char* out, size_t* out_len)
{
#if defined(HAVE_OPENSSL)
#if defined(LIBRESSL_VERSION_NUMBER)
#if (LIBRESSL_VERSION_NUMBER >= 0x2040000fL)
	const EVP_AEAD *aead = EVP_aead_chacha20_poly1305();
	EVP_AEAD_CTX ctx;
	EVP_AEAD_CTX_init(&ctx, aead, key, EVP_AEAD_key_length(aead), EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
	EVP_AEAD_CTX_open(&ctx, out, out_len, *out_len, nonce, 12, in, in_len, ad, ad_len);
#else
	unsigned char mac[16];
	unsigned char poly1305_key[32];
	poly1305_state poly1305;
	size_t plaintext_len = in_len - 16;
	uint64_t ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | nonce[2] << 16 | nonce[3] << 24) << 32;
	const unsigned char *iv = nonce + 4;

	memset(poly1305_key, 0, sizeof(poly1305_key));
	CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key, iv, ctr);

	CRYPTO_poly1305_init(&poly1305, poly1305_key);
	poly1305_update_with_pad16(&poly1305, ad, ad_len);
	poly1305_update_with_pad16(&poly1305, in, plaintext_len);
	poly1305_update_with_length(&poly1305, NULL, ad_len);
	poly1305_update_with_length(&poly1305, NULL, plaintext_len);

	CRYPTO_poly1305_finish(&poly1305, mac);

	if (memcmp(mac, in + plaintext_len, 16) != 0) {
		*out_len = 0;
		return;
	}

	CRYPTO_chacha_20(out, in, plaintext_len, key, iv, ctr + 1);
	*out_len = plaintext_len;
#endif
#elif defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
	int outl = 0;
	size_t plaintext_len = in_len - 16;
	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
	EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce);
	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, in + plaintext_len);
	EVP_DecryptUpdate(ctx, out, &outl, in, plaintext_len);
	*out_len = outl;
	outl = 0;
	if (EVP_DecryptFinal_ex(ctx, out + *out_len, &outl) == 1) {
		*out_len += outl;
	} else {
		*out_len = 0;
	}
	EVP_CIPHER_CTX_free(ctx);
#else
#error Please use a newer version of OpenSSL (>= 1.1.0)
#endif
#elif defined(HAVE_GCRYPT)
#if defined(GCRYPT_VERSION_NUMBER) && (GCRYPT_VERSION_NUMBER >= 0x010700)
	gcry_cipher_hd_t hd;
	if (gcry_cipher_open(&hd, GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_POLY1305, 0)) {
		debug_info("gcry_cipher_open() failed");
		return;
	}
	gcry_cipher_setkey(hd, key, 32);
	gcry_cipher_setiv(hd, nonce, 12);
	gcry_cipher_authenticate(hd, ad, ad_len);
	unsigned int plaintext_len = in_len - 16;
	gcry_cipher_decrypt(hd, out, *out_len, in, plaintext_len); 
	if (gcry_cipher_checktag(hd, in + plaintext_len, 16) == 0) {
		*out_len = plaintext_len;
	} else {
		*out_len = 0;
	}
	gcry_cipher_close(hd);
#else
#error Please use a newer version of libgcrypt (>= 1.7.0)
#endif
#elif defined(HAVE_MBEDTLS)
	mbedtls_chachapoly_context ctx;
	mbedtls_chachapoly_init(&ctx);
	mbedtls_chachapoly_setkey(&ctx, key);
	unsigned int plaintext_len = in_len - 16;
	if (mbedtls_chachapoly_auth_decrypt(&ctx, plaintext_len, nonce, ad, ad_len, in + plaintext_len, in, out) == 0) {
		*out_len = plaintext_len;
	} else {
		*out_len = 0;
	}
	mbedtls_chachapoly_free(&ctx);
#else
#error chacha20_poly1305_decrypt_96 is not implemented
#endif
}

static void chacha20_poly1305_decrypt_64(unsigned char* key, unsigned char* nonce, unsigned char* ad, size_t ad_len, unsigned char* in, size_t in_len, unsigned char* out, size_t* out_len)
{
	unsigned char _nonce[12];
	*(uint32_t*)(&_nonce[0]) = 0;
	memcpy(&_nonce[4], nonce, 8);
	chacha20_poly1305_decrypt_96(key, _nonce, ad, ad_len, in, in_len, out, out_len);
}
/* }}} */

#define PAIRING_ERROR(x) \
	debug_info(x); \
	if (pairing_callback) { \
		pairing_callback(LOCKDOWN_CU_PAIRING_ERROR, cb_user_data, (char*)x, NULL); \
	}

#define PAIRING_ERROR_FMT(...) \
	sprintf(tmp, __VA_ARGS__); \
	debug_info(tmp); \
	if (pairing_callback) { \
		pairing_callback(LOCKDOWN_CU_PAIRING_ERROR, cb_user_data, tmp, NULL); \
	}

#endif /* HAVE_WIRELESS_PAIRING */

LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_cu_pairing_create(lockdownd_client_t client, lockdownd_cu_pairing_cb_t pairing_callback, void* cb_user_data, plist_t host_info, plist_t acl)
{
#ifdef HAVE_WIRELESS_PAIRING
	if (!client || !pairing_callback || (host_info && plist_get_node_type(host_info) != PLIST_DICT) || (acl && plist_get_node_type(acl) != PLIST_DICT))
		return LOCKDOWN_E_INVALID_ARG;

	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	if (client->device && client->device->version == 0) {
		plist_t p_version = NULL;
		if (lockdownd_get_value(client, NULL, "ProductVersion", &p_version) == LOCKDOWN_E_SUCCESS) {
			int vers[3] = {0, 0, 0};
			char *s_version = NULL;
			plist_get_string_val(p_version, &s_version);
			if (s_version && sscanf(s_version, "%d.%d.%d", &vers[0], &vers[1], &vers[2]) >= 2) {
				client->device->version = DEVICE_VERSION(vers[0], vers[1], vers[2]);
			}
			free(s_version);
		}
		plist_free(p_version);
	}

	char* pairing_uuid = NULL;
	if (host_info) {
		plist_t accountid = plist_dict_get_item(host_info, "accountID");
		if (accountid && plist_get_node_type(accountid) == PLIST_STRING) {
			plist_get_string_val(accountid, &pairing_uuid);
		}
	}
	if (!pairing_uuid) {
		userpref_read_system_buid(&pairing_uuid);
	}
	if (!pairing_uuid) {
		pairing_uuid = generate_uuid();
	}
	unsigned int pairing_uuid_len = strlen(pairing_uuid);

	SRP_initialize_library();

	SRP* srp = SRP_new(SRP6a_sha512_client_method());
	if (!srp) {
		PAIRING_ERROR("Failed to initialize SRP")
		return LOCKDOWN_E_UNKNOWN_ERROR;
	}

	char tmp[256];
	plist_t dict = NULL;
	uint8_t current_state = 0;
	uint8_t final_state = 6;

	unsigned char* salt = NULL;
	unsigned int salt_size = 0;
	unsigned char* pubkey = NULL;
	unsigned int pubkey_size = 0;

	unsigned char setup_encryption_key[32];

	cstr *thekey = NULL;

	do {
		current_state++;

		dict = plist_new_dict();
		plist_dict_set_item(dict, "Request", plist_new_string("CUPairingCreate"));
		if (current_state == 1) {
			plist_dict_set_item(dict, "Flags", plist_new_uint(1));
		} else {
			plist_dict_set_item(dict, "Flags", plist_new_uint(0));
		}

		tlv_buf_t tlv = tlv_buf_new();

		if (current_state == 1) {
			/* send method */
			tlv_buf_append(tlv, 0x00, 1, (void*)"\x00"); // 0x00 (Method), 1 bytes, 00
		} else if (current_state == 3) {
			/* generate public key */
			cstr* own_pub = NULL;
			SRP_gen_pub(srp, &own_pub);

			if (!own_pub) {
				PAIRING_ERROR("[SRP] Failed to generate public key")
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			/* compute key from remote's public key */
			if (SRP_compute_key(srp, &thekey, pubkey, pubkey_size) != 0) {
				cstr_free(own_pub);
				PAIRING_ERROR("[SRP] Failed to compute key")
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			/* compute response */
			cstr *response = NULL;
			SRP_respond(srp, &response);

			/* send our public key + response */
			tlv_buf_append(tlv, 0x03, own_pub->length, own_pub->data);
			tlv_buf_append(tlv, 0x04, response->length, response->data);
			cstr_free(response);
			cstr_free(own_pub);
		} else if (current_state == 5) {
			/* send encrypted info */

			static const char PAIR_SETUP_ENCRYPT_SALT[] = "Pair-Setup-Encrypt-Salt";
			static const char PAIR_SETUP_ENCRYPT_INFO[] = "Pair-Setup-Encrypt-Info";
			static const char PAIR_SETUP_CONTROLLER_SIGN_SALT[] = "Pair-Setup-Controller-Sign-Salt";
			static const char PAIR_SETUP_CONTROLLER_SIGN_INFO[] = "Pair-Setup-Controller-Sign-Info";

			// HKDF with above computed key (SRP_compute_key) + Pair-Setup-Encrypt-Salt + Pair-Setup-Encrypt-Info
			// result used as key for chacha20-poly1305
			unsigned int setup_encryption_key_len = sizeof(setup_encryption_key);
			hkdf_md(MD_ALGO_SHA512, (unsigned char*)PAIR_SETUP_ENCRYPT_SALT, sizeof(PAIR_SETUP_ENCRYPT_SALT)-1, (unsigned char*)PAIR_SETUP_ENCRYPT_INFO, sizeof(PAIR_SETUP_ENCRYPT_INFO)-1, (unsigned char*)thekey->data, thekey->length, setup_encryption_key, &setup_encryption_key_len);

			unsigned char ed25519_pubkey[32];
			unsigned char ed25519_privkey[64];
			unsigned char ed25519seed[32];
			ed25519_create_seed(ed25519seed);

			ed25519_create_keypair(ed25519_pubkey, ed25519_privkey, ed25519seed);

			unsigned int signbuf_len = pairing_uuid_len + 64;
			unsigned char* signbuf = malloc(signbuf_len);
			unsigned int hkdf_len = 32;
			// HKDF with above computed key (SRP_compute_key) + Pair-Setup-Controller-Sign-Salt + Pair-Setup-Controller-Sign-Info
			hkdf_md(MD_ALGO_SHA512, (unsigned char*)PAIR_SETUP_CONTROLLER_SIGN_SALT, sizeof(PAIR_SETUP_CONTROLLER_SIGN_SALT)-1, (unsigned char*)PAIR_SETUP_CONTROLLER_SIGN_INFO, sizeof(PAIR_SETUP_CONTROLLER_SIGN_INFO)-1, (unsigned char*)thekey->data, thekey->length, signbuf, &hkdf_len);

			memcpy(signbuf + 32, pairing_uuid, pairing_uuid_len);
			memcpy(signbuf + 32 + pairing_uuid_len, ed25519_pubkey, 32);

        		unsigned char ed_sig[64];
			ed25519_sign(ed_sig, signbuf, 0x64, ed25519_pubkey, ed25519_privkey);

			tlv_buf_t tlvbuf = tlv_buf_new();
			tlv_buf_append(tlvbuf, 0x01, pairing_uuid_len, (void*)pairing_uuid);
			tlv_buf_append(tlvbuf, 0x03, sizeof(ed25519_pubkey), ed25519_pubkey);
			tlv_buf_append(tlvbuf, 0x0a, sizeof(ed_sig), ed_sig);

			/* ACL */
			unsigned char* odata = NULL;
			unsigned int olen = 0;
			if (acl) {
				opack_encode_from_plist(acl, &odata, &olen);
			} else {
				/* defaut ACL */
				plist_t acl_plist = plist_new_dict();
				plist_dict_set_item(acl_plist, "com.apple.ScreenCapture", plist_new_bool(1));	
				plist_dict_set_item(acl_plist, "com.apple.developer", plist_new_bool(1));
				opack_encode_from_plist(acl_plist, &odata, &olen);
				plist_free(acl_plist);
			}
			tlv_buf_append(tlvbuf, 0x12, olen, odata);
			free(odata);

			/* HOST INFORMATION */
			char hostname[256];
#ifdef __APPLE__
			CFStringRef cname = SCDynamicStoreCopyComputerName(NULL, NULL);
			CFStringGetCString(cname, hostname, sizeof(hostname), kCFStringEncodingUTF8);
			CFRelease(cname);
#else
#ifdef WIN32
			DWORD hostname_len = sizeof(hostname);
			GetComputerName(hostname, &hostname_len);
#else
			gethostname(hostname, sizeof(hostname));
#endif
#endif

			char modelname[256];
			modelname[0] = '\0';
#ifdef __APPLE__
			size_t len = sizeof(modelname);
			sysctlbyname("hw.model", &modelname, &len, NULL, 0);
#endif
			if (strlen(modelname) == 0) {
				strcpy(modelname, "HackbookPro13,37");
			}

			unsigned char primary_mac_addr[6] = { 0, 0, 0, 0, 0, 0 };
			if (get_primary_mac_address(primary_mac_addr) != 0) {
				debug_info("Failed to get primary mac address");
			}
			debug_info("Primary mac address: %02x:%02x:%02x:%02x:%02x:%02x\n", primary_mac_addr[0], primary_mac_addr[1], primary_mac_addr[2], primary_mac_addr[3], primary_mac_addr[4], primary_mac_addr[5]);

			// "OPACK" encoded device info
			plist_t info_plist = plist_new_dict();
			//plist_dict_set_item(info_plist, "altIRK", plist_new_data((char*)altIRK, 16));
			plist_dict_set_item(info_plist, "accountID", plist_new_string(pairing_uuid));
			plist_dict_set_item(info_plist, "model", plist_new_string(modelname));
			plist_dict_set_item(info_plist, "name", plist_new_string(hostname));
			plist_dict_set_item(info_plist, "mac", plist_new_data((char*)primary_mac_addr, 6));
			if (host_info) {
				plist_dict_merge(&info_plist, host_info);
			}
			opack_encode_from_plist(info_plist, &odata, &olen);
			plist_free(info_plist);
			tlv_buf_append(tlvbuf, 0x11, olen, odata);
			free(odata);

			size_t encrypted_len = tlvbuf->length + 16;
			unsigned char* encrypted_buf = (unsigned char*)malloc(encrypted_len);

			chacha20_poly1305_encrypt_64(setup_encryption_key, (unsigned char*)"PS-Msg05", NULL, 0, tlvbuf->data, tlvbuf->length, encrypted_buf, &encrypted_len);

			tlv_buf_free(tlvbuf);

			tlv_buf_append(tlv, 0x05, encrypted_len, encrypted_buf);
			free(encrypted_buf);
		} else {
			tlv_buf_free(tlv);
			PAIRING_ERROR("[SRP] Invalid state");
			ret = LOCKDOWN_E_PAIRING_FAILED;
			break;
		}
		tlv_buf_append(tlv, 0x06, 1, &current_state);
		plist_dict_set_item(dict, "Payload", plist_new_data((char*)tlv->data, tlv->length));
		tlv_buf_free(tlv);

		plist_dict_set_item(dict, "Label", plist_new_string(client->label));
		plist_dict_set_item(dict, "ProtocolVersion", plist_new_uint(2));

		ret = lockdownd_send(client, dict);
		plist_free(dict);
		dict = NULL;

		if (ret != LOCKDOWN_E_SUCCESS) {
			break;
		}

		current_state++;

		ret = lockdownd_receive(client, &dict);
		if (ret != LOCKDOWN_E_SUCCESS) {
			break;
		}
		ret = lockdown_check_result(dict, "CUPairingCreate");
		if (ret != LOCKDOWN_E_SUCCESS) {
			break;
		}

		plist_t extresp = plist_dict_get_item(dict, "ExtendedResponse");
		if (!extresp) {
			ret = LOCKDOWN_E_PLIST_ERROR;
			break;
		}
		plist_t blob = plist_dict_get_item(extresp, "Payload");
		if (!blob) {
			ret = LOCKDOWN_E_PLIST_ERROR;
			break;
		}
		uint64_t data_len = 0;
		const char* data = plist_get_data_ptr(blob, &data_len);

		uint8_t state = 0;
		if (!tlv_data_get_uint8(data, data_len, 0x06, &state)) {
			PAIRING_ERROR("[SRP] ERROR: Could not find state in response");
			ret = LOCKDOWN_E_PAIRING_FAILED;
			break;
		}
		if (state != current_state) {
			PAIRING_ERROR_FMT("[SRP] ERROR: Unexpected state %d, expected %d", state, current_state);
			ret = LOCKDOWN_E_PAIRING_FAILED;
			break;
		}

		unsigned int errval = 0;
		uint64_t u64val = 0;
		tlv_data_get_uint(data, data_len, 0x07, &u64val);
debug_buffer(data, data_len);
		errval = (unsigned int)u64val;
		if (errval > 0) {
			if (errval == 3) {
				u64val = 0;
				tlv_data_get_uint(data, data_len, 0x08, &u64val);
				if (u64val > 0) {
					uint32_t retry_delay = (uint32_t)u64val;
					PAIRING_ERROR_FMT("[SRP] Pairing is blocked for another %u seconds", retry_delay)
					ret = LOCKDOWN_E_PAIRING_FAILED;
					break;
				}
			} else if (errval == 2 && state == 4) {
				PAIRING_ERROR_FMT("[SRP] Invalid PIN")
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			} else {
				PAIRING_ERROR_FMT("[SRP] Received error %u in state %d.", errval, state);
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}
		}

		if (state == 2) {
			/* receive salt and public key */
			if (!tlv_data_copy_data(data, data_len, 0x02, (void**)&salt, &salt_size)) {
				PAIRING_ERROR("[SRP] ERROR: Could not find salt in response");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}
			if (!tlv_data_copy_data(data, data_len, 0x03, (void**)&pubkey, &pubkey_size)) {
				PAIRING_ERROR("[SRP] ERROR: Could not find public key in response");

				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			const char PAIR_SETUP[] = "Pair-Setup";
			if (SRP_set_user_raw(srp, (const unsigned char*)PAIR_SETUP, sizeof(PAIR_SETUP)-1) != 0) {
				PAIRING_ERROR("[SRP] Failed to set SRP user");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			/* kSRPParameters_3072_SHA512 */
			if (SRP_set_params(srp, kSRPModulus3072, sizeof(kSRPModulus3072), &kSRPGenerator5, 1, salt, salt_size) != 0) {
				PAIRING_ERROR("[SRP] Failed to set SRP parameters");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;

			}

			if (pairing_callback) {
				char pin[64];
				unsigned int pin_len = sizeof(pin);
				pairing_callback(LOCKDOWN_CU_PAIRING_PIN_REQUESTED, cb_user_data, pin, &pin_len);

				SRP_set_auth_password_raw(srp, (const unsigned char*)pin, pin_len);
			}
		} else if (state == 4) {
			/* receive proof */
			unsigned char* proof = NULL;
			unsigned int proof_len = 0;

			if (!tlv_data_copy_data(data, data_len, 0x04, (void**)&proof, &proof_len)) {
				PAIRING_ERROR("[SRP] ERROR: Could not find proof data in response");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			/* verify */
			int vrfy_result = SRP_verify(srp, proof, proof_len);
			free(proof);

			if (vrfy_result == 0) {
				debug_info("[SRP] PIN verified successfully");
			} else {
				PAIRING_ERROR("[SRP] PIN verification failure");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

		} else if (state == 6) {
			int srp_pair_success = 0;
			plist_t node = plist_dict_get_item(extresp, "doSRPPair");
			if (node) {
				const char* strv = plist_get_string_ptr(node, NULL);
				if (strcmp(strv, "succeed") == 0) {
					srp_pair_success = 1;
				}
			}
			if (!srp_pair_success) {
				PAIRING_ERROR("SRP Pairing failed");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			/* receive encrypted info */
			unsigned char* encrypted_buf = NULL;
			unsigned int enc_len = 0;
			if (!tlv_data_copy_data(data, data_len, 0x05, (void**)&encrypted_buf, &enc_len)) {
				PAIRING_ERROR("[SRP] ERROR: Could not find encrypted data in response");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}
			size_t plain_len = enc_len-16;
			unsigned char* plain_buf = malloc(plain_len);
			chacha20_poly1305_decrypt_64(setup_encryption_key, (unsigned char*)"PS-Msg06", NULL, 0, encrypted_buf, enc_len, plain_buf, &plain_len);
			free(encrypted_buf);
			
			unsigned char* dev_info = NULL;
			unsigned int dev_info_len = 0;
			int res = tlv_data_copy_data(plain_buf, plain_len, 0x11, (void**)&dev_info, &dev_info_len);
			free(plain_buf);
			if (!res) {
				PAIRING_ERROR("[SRP] ERROR: Failed to locate device info in response");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}
			plist_t device_info = NULL;
			opack_decode_to_plist(dev_info, dev_info_len, &device_info);
			free(dev_info);

			if (!device_info) {
				PAIRING_ERROR("[SRP] ERROR: Failed to parse device info");
				ret = LOCKDOWN_E_PAIRING_FAILED;
				break;
			}

			if (pairing_callback) {
				pairing_callback(LOCKDOWN_CU_PAIRING_DEVICE_INFO, cb_user_data, device_info, NULL);
			}
			plist_free(device_info);			
		} else {
			PAIRING_ERROR("[SRP] ERROR: Invalid state");
			ret = LOCKDOWN_E_PAIRING_FAILED;
			break;
		}
		plist_free(dict);
		dict = NULL;

	} while (current_state != final_state);

	plist_free(dict);

	free(salt);
	free(pubkey);

	SRP_free(srp);
	srp = NULL;

	if (ret != LOCKDOWN_E_SUCCESS) {
		if (thekey) {
			cstr_free(thekey);
		}
		return ret;
	}

	free(client->cu_key);
	client->cu_key = malloc(thekey->length);
	memcpy(client->cu_key, thekey->data, thekey->length);
	client->cu_key_len = thekey->length;
	cstr_free(thekey);

	return LOCKDOWN_E_SUCCESS;
#else
	debug_info("not supported");
	return LOCKDOWN_E_UNKNOWN_ERROR;
#endif
}

LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_cu_send_request_and_get_reply(lockdownd_client_t client, const char* request, plist_t request_payload, plist_t* reply)
{
#ifdef HAVE_WIRELESS_PAIRING
	if (!client || !request)
		return LOCKDOWN_E_INVALID_ARG;

	if (!client->cu_key)
		return LOCKDOWN_E_NO_RUNNING_SESSION;

	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	/* derive keys */
	unsigned char cu_write_key[32];
	unsigned int cu_write_key_len = sizeof(cu_write_key);
	static const char WRITE_KEY_SALT_MDLD[] = "WriteKeySaltMDLD";
	static const char WRITE_KEY_INFO_MDLD[] = "WriteKeyInfoMDLD";
	hkdf_md(MD_ALGO_SHA512, (unsigned char*)WRITE_KEY_SALT_MDLD, sizeof(WRITE_KEY_SALT_MDLD)-1, (unsigned char*)WRITE_KEY_INFO_MDLD, sizeof(WRITE_KEY_INFO_MDLD)-1, client->cu_key, client->cu_key_len, cu_write_key, &cu_write_key_len);

	unsigned char cu_read_key[32];
	unsigned int cu_read_key_len = sizeof(cu_write_key);
	static const char READ_KEY_SALT_MDLD[] = "ReadKeySaltMDLD";
	static const char READ_KEY_INFO_MDLD[] = "ReadKeyInfoMDLD";
	hkdf_md(MD_ALGO_SHA512, (unsigned char*)READ_KEY_SALT_MDLD, sizeof(READ_KEY_SALT_MDLD)-1, (unsigned char*)READ_KEY_INFO_MDLD, sizeof(READ_KEY_INFO_MDLD)-1, client->cu_key, client->cu_key_len, cu_read_key, &cu_read_key_len);

	// Starting with iOS/tvOS 11.2 and WatchOS 4.2, this nonce is random and sent along with the request. Before, the request doesn't have a nonce and it uses hardcoded nonce "sendone01234".
	unsigned char cu_nonce[12] = "sendone01234"; // guaranteed to be random by fair dice troll
        if (client->device->version >= DEVICE_VERSION(11,2,0)) {
#if defined(HAVE_OPENSSL)
		RAND_bytes(cu_nonce, sizeof(cu_nonce));
#elif defined(HAVE_GCRYPT)
		gcry_create_nonce(cu_nonce, sizeof(cu_nonce));
#endif
	}

	debug_plist(request_payload);

	/* convert request payload to binary */
	uint32_t bin_len = 0;
	char* bin = NULL;
	plist_to_bin(request_payload, &bin, &bin_len);

	/* encrypt request */
	size_t encrypted_len = bin_len + 16;
	unsigned char* encrypted_buf = malloc(encrypted_len);
	chacha20_poly1305_encrypt_96(cu_write_key, cu_nonce, NULL, 0, (unsigned char*)bin, bin_len, encrypted_buf, &encrypted_len);
	free(bin);
	bin = NULL;

	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict,"Request", plist_new_string(request));
	plist_dict_set_item(dict, "Payload", plist_new_data((char*)encrypted_buf, encrypted_len));
	free(encrypted_buf);
	plist_dict_set_item(dict, "Nonce", plist_new_data((char*)cu_nonce, sizeof(cu_nonce)));
	plist_dict_set_item(dict, "Label", plist_new_string(client->label));
	plist_dict_set_item(dict, "ProtocolVersion", plist_new_uint(2));

	/* send to device */
	ret = lockdownd_send(client, dict);
	plist_free(dict);
	dict = NULL;

	if (ret != LOCKDOWN_E_SUCCESS)
		return ret;

	/* Now get device's answer */
	ret = lockdownd_receive(client, &dict);
	if (ret != LOCKDOWN_E_SUCCESS)
		return ret;

	ret = lockdown_check_result(dict, request);
	if (ret != LOCKDOWN_E_SUCCESS) {
		plist_free(dict);
		return ret;
	}

	/* get payload */
	plist_t blob = plist_dict_get_item(dict, "Payload");
	if (!blob) {
		plist_free(dict);
		return LOCKDOWN_E_DICT_ERROR;
	}

	uint64_t dl = 0;
	const char* dt = plist_get_data_ptr(blob, &dl);

	/* see if we have a nonce */
	blob = plist_dict_get_item(dict, "Nonce");
	const unsigned char* rnonce = (unsigned char*)"receiveone01";
	if (blob) {
		uint64_t rl = 0;
		rnonce = (const unsigned char*)plist_get_data_ptr(blob, &rl);
	}

	/* decrypt payload */
	size_t decrypted_len = dl-16;
	unsigned char* decrypted = malloc(decrypted_len);
	chacha20_poly1305_decrypt_96(cu_read_key, (unsigned char*)rnonce, NULL, 0, (unsigned char*)dt, dl, decrypted, &decrypted_len);
	plist_free(dict);
	dict = NULL;

	plist_from_memory((const char*)decrypted, decrypted_len, &dict);
	if (!dict) {
		ret = LOCKDOWN_E_PLIST_ERROR;
		debug_info("Failed to parse PLIST from decrypted payload:");
		debug_buffer((const char*)decrypted, decrypted_len);
		free(decrypted);
		return ret;	
	}
	free(decrypted);

	debug_plist(dict);

	if (reply) {
		*reply = dict;
	} else {
		plist_free(dict);
	}

	return LOCKDOWN_E_SUCCESS;
#else
	debug_info("not supported");
	return LOCKDOWN_E_UNKNOWN_ERROR;
#endif
}

LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_value_cu(lockdownd_client_t client, const char* domain, const char* key, plist_t* value)
{
#ifdef HAVE_WIRELESS_PAIRING
	if (!client)
		return LOCKDOWN_E_INVALID_ARG;

	if (!client->cu_key)
		return LOCKDOWN_E_NO_RUNNING_SESSION;

	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	plist_t request = plist_new_dict();
	if (domain) {
		plist_dict_set_item(request, "Domain", plist_new_string(domain));
	}
	if (key) {
		plist_dict_set_item(request, "Key", plist_new_string(key));
	}

	plist_t reply = NULL;
	ret = lockdownd_cu_send_request_and_get_reply(client, "GetValueCU", request, &reply);
	plist_free(request);
	if (ret != LOCKDOWN_E_SUCCESS) {
		return ret;
	}

	plist_t value_node = plist_dict_get_item(reply, "Value");
	if (value_node) {
		debug_info("has a value");
		*value = plist_copy(value_node);
	}
	plist_free(reply);

	return ret;
#else
	debug_info("not supported");
	return LOCKDOWN_E_UNKNOWN_ERROR;
#endif
}

LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_pair_cu(lockdownd_client_t client)
{
#ifdef HAVE_WIRELESS_PAIRING
	if (!client)
		return LOCKDOWN_E_INVALID_ARG;

	if (!client->cu_key)
		return LOCKDOWN_E_NO_RUNNING_SESSION;

	lockdownd_error_t ret;

	plist_t wifi_mac = NULL;
	ret = lockdownd_get_value_cu(client, NULL, "WiFiAddress", &wifi_mac);
	if (ret != LOCKDOWN_E_SUCCESS) {
		return ret;
	}

	plist_t pubkey = NULL;
	ret = lockdownd_get_value_cu(client, NULL, "DevicePublicKey", &pubkey);
	if (ret != LOCKDOWN_E_SUCCESS) {
		plist_free(wifi_mac);
		return ret;
	}	

	key_data_t public_key = { NULL, 0 };
	uint64_t data_len = 0;
	plist_get_data_val(pubkey, (char**)&public_key.data, &data_len);
	public_key.size = (unsigned int)data_len;
	plist_free(pubkey);	

	plist_t pair_record_plist = plist_new_dict();
	pair_record_generate_keys_and_certs(pair_record_plist, public_key);

	char* host_id = NULL;
	char* system_buid = NULL;

	/* set SystemBUID */
	userpref_read_system_buid(&system_buid);
	if (system_buid) {
		plist_dict_set_item(pair_record_plist, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid));
		free(system_buid);
	}

	/* set HostID */
	host_id = generate_uuid();
	pair_record_set_host_id(pair_record_plist, host_id);
	free(host_id);

	plist_t request_pair_record = plist_copy(pair_record_plist);
	/* remove stuff that is private */
	plist_dict_remove_item(request_pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY);
	plist_dict_remove_item(request_pair_record, USERPREF_HOST_PRIVATE_KEY_KEY);

	plist_t request = plist_new_dict();
	plist_dict_set_item(request, "PairRecord", request_pair_record);
	plist_t pairing_opts = plist_new_dict();
	plist_dict_set_item(pairing_opts, "ExtendedPairingErrors", plist_new_bool(1));
	plist_dict_set_item(request, "PairingOptions", pairing_opts);

	plist_t reply = NULL;
	ret = lockdownd_cu_send_request_and_get_reply(client, "PairCU", request, &reply);
	plist_free(request);
	if (ret != LOCKDOWN_E_SUCCESS) {
		plist_free(wifi_mac);
		return ret;
	}

	char *s_udid = NULL;
	plist_t p_udid = plist_dict_get_item(reply, "UDID");
	if (p_udid) {
		plist_get_string_val(p_udid, &s_udid);
	}
	plist_t ebag = plist_dict_get_item(reply, "EscrowBag");
	if (ebag) {
		plist_dict_set_item(pair_record_plist, USERPREF_ESCROW_BAG_KEY, plist_copy(ebag));
	}
	plist_dict_set_item(pair_record_plist, USERPREF_WIFI_MAC_ADDRESS_KEY, wifi_mac);
	plist_free(reply);

	if (userpref_save_pair_record(s_udid, 0, pair_record_plist) != 0) {
		printf("Failed to save pair record for UDID %s\n", s_udid);
	}
	free(s_udid);
	s_udid = NULL;
	plist_free(pair_record_plist);

	ret = LOCKDOWN_E_SUCCESS;		

	return ret;
#else
	debug_info("not supported");
	return LOCKDOWN_E_UNKNOWN_ERROR;
#endif
}
