summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml33
-rw-r--r--README.md223
-rw-r--r--configure.ac36
-rw-r--r--src/Makefile.am8
-rw-r--r--src/asr.c19
-rw-r--r--src/dfu.c3
-rw-r--r--src/fixedint.h72
-rw-r--r--src/idevicerestore.c21
-rw-r--r--src/img4.c3
-rw-r--r--src/ipsw.c18
-rw-r--r--src/normal.c2
-rw-r--r--src/recovery.c3
-rw-r--r--src/restore.c2
-rw-r--r--src/sha1.c294
-rw-r--r--src/sha1.h44
-rw-r--r--src/sha512.c314
-rw-r--r--src/sha512.h32
-rw-r--r--src/tss.c1794
-rw-r--r--src/tss.h76
19 files changed, 229 insertions, 2768 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 76d4a0b..bd2bdd5 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -48,6 +48,13 @@ jobs:
workflow: build.yml
name: libimobiledevice-latest_${{env.target_triplet}}
repo: libimobiledevice/libimobiledevice
+ - name: fetch libtatsu
+ uses: dawidd6/action-download-artifact@v3
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: build.yml
+ name: libtatsu-latest_${{env.target_triplet}}
+ repo: libimobiledevice/libtatsu
- name: install external dependencies
run: |
mkdir extract
@@ -122,6 +129,13 @@ jobs:
workflow: build.yml
name: libimobiledevice-latest_macOS
repo: libimobiledevice/libimobiledevice
+ - name: fetch libtatsu
+ uses: dawidd6/action-download-artifact@v3
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: build.yml
+ name: libtatsu-latest_macOS
+ repo: libimobiledevice/libtatsu
- name: install external dependencies
run: |
mkdir extract
@@ -144,18 +158,7 @@ jobs:
export CFLAGS="$USEARCHS -isysroot $SDKDIR"
echo "Using CFLAGS: $CFLAGS"
echo "BUILD_CFLAGS=$CFLAGS" >> $GITHUB_ENV
- mkdir -p lib
- curl -o lib/libcrypto.35.tbd -Ls \
- https://gist.github.com/nikias/94c99fd145a75a5104415e5117b0cafa/raw/5209dfbff5a871a14272afe4794e76eb4cf6f062/libcrypto.35.tbd
- curl -o lib/libssl.35.tbd -Ls \
- https://gist.github.com/nikias/94c99fd145a75a5104415e5117b0cafa/raw/5209dfbff5a871a14272afe4794e76eb4cf6f062/libssl.35.tbd
- LIBRESSL_VER=2.2.7
- FILENAME="libressl-$LIBRESSL_VER.tar.gz"
- curl -o $FILENAME -Ls "https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/$FILENAME"
mkdir -p deps
- tar -C deps -xzf $FILENAME
- echo "LIBRESSL_CFLAGS=-I`pwd`/deps/libressl-$LIBRESSL_VER/include" >> $GITHUB_ENV
- echo "LIBRESSL_LIBS=-Xlinker `pwd`/lib/libssl.35.tbd -Xlinker `pwd`/lib/libcrypto.35.tbd" >> $GITHUB_ENV
FILENAME="libzip-static.tar.bz2"
curl -o $FILENAME.b64 -Ls "https://gist.github.com/nikias/3da15d03120382f87b44029cd8495a02/raw/99cd8138fed99e8f6530b6f179f787342c698e1f/libzip-1.7.1_static_macOS.tar.bz2"
base64 -D < $FILENAME.b64 > $FILENAME
@@ -167,7 +170,6 @@ jobs:
export CFLAGS="${{env.BUILD_CFLAGS}} -Wno-nullability-completeness -Wno-expansion-to-defined"
echo "Using CFLAGS: $CFLAGS"
./autogen.sh PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \
- openssl_CFLAGS="$LIBRESSL_CFLAGS" openssl_LIBS="$LIBRESSL_LIBS" \
libcurl_CFLAGS="-I${{env.SDKDIR}}/usr/include" libcurl_LIBS="-lcurl" \
libzip_CFLAGS="$LIBZIP_CFLAGS" libzip_LIBS="$LIBZIP_LIBS" \
zlib_CFLAGS="-I${{env.SDKDIR}}/usr/include" zlib_LIBS="-lz" \
@@ -253,6 +255,13 @@ jobs:
workflow: build.yml
name: libimobiledevice-latest_${{ matrix.arch }}-${{ env.dest }}
repo: libimobiledevice/libimobiledevice
+ - name: fetch libtatsu
+ uses: dawidd6/action-download-artifact@v3
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: build.yml
+ name: libtatsu-latest_${{ matrix.arch }}-${{ env.dest }}
+ repo: libimobiledevice/libtatsu
- name: install external dependencies
run: |
mkdir extract
diff --git a/README.md b/README.md
index 3b52567..1af2d93 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,21 @@
![](https://github.com/libimobiledevice/idevicerestore/actions/workflows/build.yml/badge.svg)
+## Table of Contents
+- [Features](#features)
+- [Building](#building)
+ - [Prerequisites](#prerequisites)
+ - [Linux (Debian/Ubuntu based)](#linux-debianubuntu-based)
+ - [macOS](#macos)
+ - [Windows](#windows)
+ - [Configuring the source tree](#configuring-the-source-tree)
+ - [Building and installation](#building-and-installation)
+- [Usage](#usage)
+- [Contributing](#contributing)
+- [Links](#links)
+- [License](#license)
+- [Credits](#credits)
+
## Features
The idevicerestore application is a full reimplementation of all granular steps
@@ -33,56 +48,176 @@ Use with caution and make sure to backup your data before trying to restore.
**In any case, usage is at your own risk.**
-## Installation / Getting started
-
-### Debian / Ubuntu Linux
+## Building
+
+### Prerequisites
+
+You need to have a working compiler (gcc/clang) and development environent
+available. This project uses autotools for the build process, allowing to
+have common build steps across different platforms.
+Only the prerequisites differ and they are described in this section.
+
+#### Linux (Debian/Ubuntu based)
+
+* Install all required dependencies and build tools:
+ ```shell
+ sudo apt-get install \
+ build-essential \
+ pkg-config \
+ checkinstall \
+ git \
+ autoconf \
+ automake \
+ libtool-bin \
+ libreadline-dev \
+ libusb-1.0-0-dev \
+ libplist-dev \
+ libimobiledevice-dev \
+ libimobiledevice-glue-dev \
+ libtatsu-dev \
+ libcurl4-openssl-dev \
+ libssl-dev \
+ libzip-dev \
+ zlib1g-dev
+ ```
+ NOTE: [libtatsu](https://github.com/libimobiledevice/libtatsu) (and thus `libtatsu-dev`)
+ is a new library that was just published recently, you have to
+ [build it from source](https://github.com/libimobiledevice/libtatsu?tab=readme-ov-file#building).
+ Also, other `*-dev` packages might not be available for your distribution,
+ so you will have to build these packages on your own as well.
+
+#### macOS
+
+* Make sure the Xcode command line tools are installed.
+
+ **Option 1**:
+ The easiest way to build and install `idevicerestore` for macOS is using
+ the following build script which will do the work for you, it will build
+ and install all required dependencies:
+ ```bash
+ mkdir -p limd-build
+ cd limd-build
+ curl -o ./limd-build-macos.sh -L https://is.gd/limdmacos
+ bash ./limd-build-macos.sh
+ ```
+ Follow the prompts of the script and you should have a working `idevicerestore`
+ available.
+
+ **Option 2**:
+ Use either [MacPorts](https://www.macports.org/)
+ or [Homebrew](https://brew.sh/) to install `automake`, `autoconf`, and `libtool`.
+
+ Using MacPorts:
+ ```shell
+ sudo port install libtool autoconf automake
+ ```
+
+ Using Homebrew:
+ ```shell
+ brew install libtool autoconf automake
+ ```
+
+ `idevicerestore` has a few dependencies from the libimobiledevice project.
+ You will have to build and install the following:
+ * [libplist](https://github.com/libimobiledevice/libplist)
+ * [libimobiledevice-glue](https://github.com/libimobiledevice/libimobiledevice-glue)
+ * [libusbmuxd](https://github.com/libimobiledevice/libusbmuxd)
+ * [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice)
+ * [libirecovery](https://github.com/libimobiledevice/libirecovery)
+ * [libtatsu](https://github.com/libimobiledevice/libtatsu)
+
+ Check their `README.md` for building and installation instructions.
+
+#### Windows
+
+* Using [MSYS2](https://www.msys2.org/) is the official way of compiling this project on Windows. Download the MSYS2 installer
+ and follow the installation steps.
+
+ It is recommended to use the _MSYS2 MinGW 64-bit_ shell. Run it and make sure the required dependencies are installed:
+
+ ```shell
+ pacman -S base-devel \
+ git \
+ mingw-w64-x86_64-gcc \
+ make \
+ libtool \
+ autoconf \
+ automake-wrapper
+ ```
+ NOTE: You can use a different shell and different compiler according to your needs. Adapt the above command accordingly.
+
+ `idevicerestore` has a few dependencies from the libimobiledevice project.
+ You will have to build and install the following:
+ * [libplist](https://github.com/libimobiledevice/libplist)
+ * [libimobiledevice-glue](https://github.com/libimobiledevice/libimobiledevice-glue)
+ * [libusbmuxd](https://github.com/libimobiledevice/libusbmuxd)
+ * [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice)
+ * [libirecovery](https://github.com/libimobiledevice/libirecovery)
+ * [libtatsu](https://github.com/libimobiledevice/libtatsu)
+
+ Check their `README.md` for building and installation instructions.
+
+
+### Configuring the source tree
+
+You can build the source code from a git checkout, or from a `.tar.bz2` release tarball from [Releases](https://github.com/libimobiledevice/idevicerestore/releases).
+Before we can build it, the source tree has to be configured for building. The steps depend on where you got the source from.
+
+* **From git**
+
+ If you haven't done already, clone the actual project repository and change into the directory.
+ ```shell
+ git clone https://github.com/libimobiledevice/idevicerestore.git
+ cd idevicerestore
+ ```
+
+ Configure the source tree for building:
+ ```shell
+ ./autogen.sh
+ ```
+
+* **From release tarball (.tar.bz2)**
+
+ When using an official [release tarball](https://github.com/libimobiledevice/idevicerestore/releases) (`idevicerestore-x.y.z.tar.bz2`)
+ the procedure is slightly different.
+
+ Extract the tarball:
+ ```shell
+ tar xjf idevicerestore-x.y.z.tar.bz2
+ cd idevicerestore-x.y.z
+ ```
+
+ Configure the source tree for building:
+ ```shell
+ ./configure
+ ```
+
+Both `./configure` and `./autogen.sh` (which generates and calls `configure`) accept a few options, for example `--prefix` to allow
+building for a different target folder. You can simply pass them like this:
-First install all required dependencies and build tools:
```shell
-sudo apt-get install \
- build-essential \
- pkg-config \
- checkinstall \
- git \
- autoconf \
- automake \
- libtool-bin \
- libreadline-dev \
- libusb-1.0-0-dev \
- libplist-dev \
- libimobiledevice-dev \
- libimobiledevice-glue-dev \
- libcurl4-openssl-dev \
- libssl-dev \
- libzip-dev \
- zlib1g-dev
+./autogen.sh --prefix=/usr/local
```
-
-Then clone, build and install [libirecovery](https://github.com/libimobiledevice/libirecovery.git) which is not yet packaged:
+or
```shell
-git clone https://github.com/libimobiledevice/libirecovery.git
-cd libirecovery
-./autogen.sh
-make
-sudo make install
-cd ..
+./configure --prefix=/usr/local
```
-If the configure processes indicates old or missing libraries, your distribution
-might not have yet packaged the latest versions. In that case you will have to
-clone [these libraries](https://github.com/libimobiledevice/) separately and repeat the process in order to proceed.
-
-Continue with cloning the actual project repository:
-```shell
-git clone https://github.com/libimobiledevice/idevicerestore.git
-cd idevicerestore
+Once the command is successful, the last few lines of output will look like this:
```
+[...]
+config.status: creating config.h
+config.status: config.h is unchanged
+config.status: executing depfiles commands
+config.status: executing libtool commands
-Now you can build and install it:
-```shell
-./autogen.sh
-make
-sudo make install
+Configuration for idevicerestore 1.1.0:
+-------------------------------------------
+
+ Install prefix: .........: /usr/local
+
+ Now type 'make' to build idevicerestore 1.1.0,
+ and then 'make install' for installation.
```
**Important**
@@ -142,8 +277,6 @@ Please make sure your contribution adheres to:
* Try to split larger changes into individual commits of a common domain
* Use your real name and a valid email address for your commits
-We are still working on the guidelines so bear with us!
-
## Links
* Homepage: https://libimobiledevice.org/
@@ -166,4 +299,4 @@ iPadOS, tvOS, watchOS, and macOS are trademarks of Apple Inc.
This project is an independent software application and has not been
authorized, sponsored, or otherwise approved by Apple Inc.
-README Updated on: 2022-04-04
+README Updated on: 2024-06-19
diff --git a/configure.ac b/configure.ac
index 0b5fcea..d0a052f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,19 +19,19 @@ LIBIRECOVERY_VERSION=1.2.0
LIBIMOBILEDEVICE_VERSION=1.3.0
LIBUSBMUXD_VERSION=2.0.2
LIBPLIST_VERSION=2.6.0
-LIMD_GLUE_VERSION=1.2.0
+LIMD_GLUE_VERSION=1.3.0
+LIBTATSU_VERSION=1.0.3
LIBZIP_VERSION=1.0
LIBCURL_VERSION=7.0
-OPENSSL_VERSION=0.9.8
AC_SUBST(LIBIRECOVERY_VERSION)
AC_SUBST(LIBIMOBILEDEVICE_VERSION)
AC_SUBST(LIBUSBMUXD_VERSION)
AC_SUBST(LIBPLIST_VERSION)
AC_SUBST(LIMD_GLUE_VERSION)
+AC_SUBST(LIBTATSU_VERSION)
AC_SUBST(LIBZIP_VERSION)
AC_SUBST(LIBCURL_VERSION)
-AC_SUBST(OPENSSL_VERSION)
# Checks for programs.
AC_PROG_CC
@@ -44,13 +44,11 @@ PKG_CHECK_MODULES(libimobiledevice, libimobiledevice-1.0 >= $LIBIMOBILEDEVICE_VE
PKG_CHECK_MODULES(libusbmuxd, libusbmuxd-2.0 >= $LIBUSBMUXD_VERSION)
PKG_CHECK_MODULES(libplist, libplist-2.0 >= $LIBPLIST_VERSION)
PKG_CHECK_MODULES(limd_glue, libimobiledevice-glue-1.0 >= $LIMD_GLUE_VERSION)
+PKG_CHECK_MODULES(libtatsu, libtatsu-1.0 >= $LIBTATSU_VERSION)
PKG_CHECK_MODULES(libzip, libzip >= $LIBZIP_VERSION)
PKG_CHECK_MODULES(libcurl, libcurl >= $LIBCURL_VERSION)
PKG_CHECK_MODULES(zlib, zlib)
-# optional
-PKG_CHECK_MODULES(openssl, openssl >= $OPENSSL_VERSION, have_openssl=yes, have_openssl=no)
-
AC_CHECK_FUNCS([strsep strcspn mkstemp realpath])
if test x$ac_cv_func_strsep != xyes; then
if test x$ac_cv_func_strcspn != xyes; then
@@ -153,32 +151,6 @@ fi
CFLAGS="$CACHED_CFLAGS"
-AC_ARG_WITH([openssl],
- [AS_HELP_STRING([--without-openssl],
- [Do not use OpenSSL])],
- [use_openssl=$withval],
- [use_openssl=$have_openssl])
-
-if test "x$use_openssl" == "xyes"; then
- if test "x$have_openssl" != "xyes"; then
- echo "*** NOTE: --with-openssl passed but OpenSSL is not available ***"
- use_openssl=no
- fi
-fi
-if test "x$use_openssl" != "xyes"; then
- echo "*** NOTE: Using internal SHA1 implementation ***"
- have_openssl=no
- openssl_CFLAGS=
- openssl_LIBS=
-fi
-if test "x$have_openssl" == "xyes"; then
- AC_DEFINE(HAVE_OPENSSL, [1], [Define if you have OpenSSL])
-fi
-AC_SUBST(openssl_CFLAGS)
-AC_SUBST(openssl_LIBS)
-
-AM_CONDITIONAL(USE_INTERNAL_SHA, test x$use_openssl != xyes)
-
AC_SUBST(GLOBAL_CFLAGS)
AC_SUBST(AC_LDFLAGS)
AC_SUBST(AC_LDADD)
diff --git a/src/Makefile.am b/src/Makefile.am
index 722487a..80f02f2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,9 +6,9 @@ AM_CFLAGS = \
$(libusbmuxd_CFLAGS) \
$(libplist_CFLAGS) \
$(limd_glue_CFLAGS) \
+ $(libtatsu_CFLAGS) \
$(libzip_CFLAGS) \
$(zlib_CFLAGS) \
- $(openssl_CFLAGS) \
$(libcurl_CFLAGS)
AM_LDFLAGS = \
@@ -18,9 +18,9 @@ AM_LDFLAGS = \
$(libusbmuxd_LIBS) \
$(libplist_LIBS) \
$(limd_glue_LIBS) \
+ $(libtatsu_LIBS) \
$(libzip_LIBS) \
$(zlib_LIBS) \
- $(openssl_LIBS) \
$(libcurl_LIBS)
AM_LDADD = $(AC_LDADD)
@@ -31,7 +31,6 @@ idevicerestore_SOURCES = \
idevicerestore.c idevicerestore.h \
endianness.h \
common.c common.h \
- tss.c tss.h \
fls.c fls.h \
mbn.c mbn.h \
img3.c img3.h \
@@ -49,9 +48,6 @@ idevicerestore_SOURCES = \
limera1n.c limera1n.h \
download.c download.h \
locking.c locking.h
-if USE_INTERNAL_SHA
-idevicerestore_SOURCES += sha1.c sha1.h sha512.c sha512.h fixedint.h
-endif
idevicerestore_CFLAGS = $(AM_CFLAGS)
idevicerestore_LDFLAGS = $(AM_LDFLAGS)
idevicerestore_LDADD = $(AM_LDADD)
diff --git a/src/asr.c b/src/asr.c
index bf15dc2..aadf25a 100644
--- a/src/asr.c
+++ b/src/asr.c
@@ -30,15 +30,8 @@
#include <unistd.h>
#include <errno.h>
#include <libimobiledevice/libimobiledevice.h>
-#ifdef HAVE_OPENSSL
-#include <openssl/sha.h>
-#else
-#include "sha1.h"
-#define SHA_CTX SHA1_CTX
-#define SHA1_Init SHA1Init
-#define SHA1_Update SHA1Update
-#define SHA1_Final SHA1Final
-#endif
+
+#include <libimobiledevice-glue/sha.h>
#include "asr.h"
#include "idevicerestore.h"
@@ -343,12 +336,6 @@ int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file)
data = (char*)malloc(ASR_PAYLOAD_CHUNK_SIZE + 20);
- SHA_CTX sha1;
-
- if (asr->checksum_chunks) {
- SHA1_Init(&sha1);
- }
-
i = length;
int retry = 3;
while(i > 0 && retry >= 0) {
@@ -367,7 +354,7 @@ int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file)
sendsize = size;
if (asr->checksum_chunks) {
- SHA1((unsigned char*)data, size, (unsigned char*)(data+size));
+ sha1((unsigned char*)data, size, (unsigned char*)(data+size));
sendsize += 20;
}
if (asr_send_buffer(asr, data, sendsize) < 0) {
diff --git a/src/dfu.c b/src/dfu.c
index cc8e1fb..8557c29 100644
--- a/src/dfu.c
+++ b/src/dfu.c
@@ -27,8 +27,9 @@
#include <unistd.h>
#include <libirecovery.h>
+#include <libtatsu/tss.h>
+
#include "dfu.h"
-#include "tss.h"
#include "recovery.h"
#include "idevicerestore.h"
#include "common.h"
diff --git a/src/fixedint.h b/src/fixedint.h
deleted file mode 100644
index 1a8745b..0000000
--- a/src/fixedint.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Portable header to provide the 32 and 64 bits type.
-
- Not a compatible replacement for <stdint.h>, do not blindly use it as such.
-*/
-
-#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED)
- #include <stdint.h>
- #define FIXEDINT_H_INCLUDED
-
- #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
- #include <limits.h>
- #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
- #endif
-#endif
-
-
-#ifndef FIXEDINT_H_INCLUDED
- #define FIXEDINT_H_INCLUDED
-
- #include <limits.h>
-
- /* (u)int32_t */
- #ifndef uint32_t
- #if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long uint32_t;
- #elif (UINT_MAX == 0xffffffffUL)
- typedef unsigned int uint32_t;
- #elif (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short uint32_t;
- #endif
- #endif
-
-
- #ifndef int32_t
- #if (LONG_MAX == 0x7fffffffL)
- typedef signed long int32_t;
- #elif (INT_MAX == 0x7fffffffL)
- typedef signed int int32_t;
- #elif (SHRT_MAX == 0x7fffffffL)
- typedef signed short int32_t;
- #endif
- #endif
-
-
- /* (u)int64_t */
- #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L)
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-
- #define UINT64_C(v) v ##ULL
- #define INT64_C(v) v ##LL
- #elif defined(__GNUC__)
- __extension__ typedef long long int64_t;
- __extension__ typedef unsigned long long uint64_t;
-
- #define UINT64_C(v) v ##ULL
- #define INT64_C(v) v ##LL
- #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC)
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-
- #define UINT64_C(v) v ##ULL
- #define INT64_C(v) v ##LL
- #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
-
- #define UINT64_C(v) v ##UI64
- #define INT64_C(v) v ##I64
- #endif
-#endif
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index f27c357..309f2b6 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -38,18 +38,12 @@
#include <curl/curl.h>
-#ifdef HAVE_OPENSSL
-#include <openssl/sha.h>
-#else
-#include "sha512.h"
-#define SHA384 sha384
-#endif
-
+#include <libimobiledevice-glue/sha.h>
#include <libimobiledevice-glue/utils.h>
+#include <libtatsu/tss.h>
#include "ace3.h"
#include "dfu.h"
-#include "tss.h"
#include "img3.h"
#include "img4.h"
#include "ipsw.h"
@@ -359,6 +353,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
idevice_set_debug_level(1);
irecv_set_debug_level(1);
}
+ tss_set_debug_level(client->debug_level);
}
idevicerestore_progress(client, RESTORE_STEP_DETECT, 0.0);
@@ -1494,7 +1489,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
// device is finally in restore mode, let's do this
if (client->mode == MODE_RESTORE) {
if ((client->flags & FLAG_NO_RESTORE) != 0) {
- info("Device is now in restore mode. Exiting as requested.");
+ info("Device is now in restore mode. Exiting as requested.\n");
return 0;
}
client->ignore_device_add_events = 1;
@@ -2169,7 +2164,7 @@ int get_preboard_manifest(struct idevicerestore_client_t* client, plist_t build_
return -1;
}
- plist_dict_set_item(parameters, "_OnlyFWOrTrustedComponents", plist_new_bool(1));
+ plist_dict_set_item(parameters, "_OnlyFWComponents", plist_new_bool(1));
/* add tags from manifest */
if (tss_request_add_ap_tags(request, parameters, NULL) < 0) {
@@ -2494,7 +2489,7 @@ int get_recovery_os_local_policy_tss_response(
// Add Ap,LocalPolicy
uint8_t digest[SHA384_DIGEST_LENGTH];
- SHA384(lpol_file, lpol_file_length, digest);
+ sha384(lpol_file, lpol_file_length, digest);
plist_t lpol = plist_new_dict();
plist_dict_set_item(lpol, "Digest", plist_new_data((char*)digest, SHA384_DIGEST_LENGTH));
plist_dict_set_item(lpol, "Trusted", plist_new_bool(1));
@@ -2589,7 +2584,7 @@ int get_local_policy_tss_response(struct idevicerestore_client_t* client, plist_
// Add Ap,LocalPolicy
uint8_t digest[SHA384_DIGEST_LENGTH];
- SHA384(lpol_file, lpol_file_length, digest);
+ sha384(lpol_file, lpol_file_length, digest);
plist_t lpol = plist_new_dict();
plist_dict_set_item(lpol, "Digest", plist_new_data((char*)digest, SHA384_DIGEST_LENGTH));
plist_dict_set_item(lpol, "Trusted", plist_new_bool(1));
@@ -2602,7 +2597,7 @@ int get_local_policy_tss_response(struct idevicerestore_client_t* client, plist_
tss_response_get_ap_img4_ticket(client->tss, &ticket, &ticket_length);
// Hash it and add it as Ap,NextStageIM4MHash
uint8_t hash[SHA384_DIGEST_LENGTH];
- SHA384(ticket, ticket_length, hash);
+ sha384(ticket, ticket_length, hash);
plist_dict_set_item(parameters, "Ap,NextStageIM4MHash", plist_new_data((char*)hash, SHA384_DIGEST_LENGTH));
/* create basic request */
diff --git a/src/img4.c b/src/img4.c
index 9a0cb29..cfd3c93 100644
--- a/src/img4.c
+++ b/src/img4.c
@@ -22,9 +22,10 @@
#include <stdlib.h>
#include <string.h>
+#include <libtatsu/tss.h>
+
#include "common.h"
#include "img4.h"
-#include "tss.h"
#define ASN1_PRIVATE 0xc0
#define ASN1_PRIMITIVE_TAG 0x1f
diff --git a/src/ipsw.c b/src/ipsw.c
index c25f61d..6a747f4 100644
--- a/src/ipsw.c
+++ b/src/ipsw.c
@@ -34,16 +34,8 @@
#include <sys/types.h>
#include <dirent.h>
#include <zip.h>
-#ifdef HAVE_OPENSSL
-#include <openssl/sha.h>
-#else
-#include "sha1.h"
-#define SHA_CTX SHA1_CTX
-#define SHA1_Init SHA1Init
-#define SHA1_Update SHA1Update
-#define SHA1_Final SHA1Final
-#endif
+#include <libimobiledevice-glue/sha.h>
#include <libimobiledevice-glue/termcolors.h>
#include <plist/plist.h>
@@ -1176,14 +1168,14 @@ static int sha1_verify_fp(FILE* f, unsigned char* expected_sha1)
unsigned char tsha1[20];
char buf[8192];
if (!f) return 0;
- SHA_CTX sha1ctx;
- SHA1_Init(&sha1ctx);
+ sha1_context sha1ctx;
+ sha1_init(&sha1ctx);
rewind(f);
while (!feof(f)) {
size_t sz = fread(buf, 1, 8192, f);
- SHA1_Update(&sha1ctx, (const void*)buf, sz);
+ sha1_update(&sha1ctx, buf, sz);
}
- SHA1_Final(tsha1, &sha1ctx);
+ sha1_final(&sha1ctx, tsha1);
return (memcmp(expected_sha1, tsha1, 20) == 0) ? 1 : 0;
}
diff --git a/src/normal.c b/src/normal.c
index 8070982..e699bbe 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -333,7 +333,7 @@ static int normal_get_nonce_by_key(struct idevicerestore_client_t* client, const
}
uint64_t n_size = 0;
- plist_get_data_val(nonce_node, nonce, &n_size);
+ plist_get_data_val(nonce_node, (char**)nonce, &n_size);
*nonce_size = (unsigned int)n_size;
plist_free(nonce_node);
diff --git a/src/recovery.c b/src/recovery.c
index e3fb4d1..afda4a9 100644
--- a/src/recovery.c
+++ b/src/recovery.c
@@ -29,8 +29,9 @@
#include <libimobiledevice/restore.h>
#include <libimobiledevice/libimobiledevice.h>
+#include <libtatsu/tss.h>
+
#include "idevicerestore.h"
-#include "tss.h"
#include "img3.h"
#include "restore.h"
#include "recovery.h"
diff --git a/src/restore.c b/src/restore.c
index 050ee3b..efb03f9 100644
--- a/src/restore.c
+++ b/src/restore.c
@@ -38,6 +38,7 @@
#endif
#include <zip.h>
#include <libirecovery.h>
+#include <libtatsu/tss.h>
#include "idevicerestore.h"
#include "asr.h"
@@ -45,7 +46,6 @@
#include "fls.h"
#include "mbn.h"
#include "ftab.h"
-#include "tss.h"
#include "ipsw.h"
#include "restore.h"
#include "common.h"
diff --git a/src/sha1.c b/src/sha1.c
deleted file mode 100644
index 02557ff..0000000
--- a/src/sha1.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-Test Vectors (from FIPS PUB 180-1)
-"abc"
- A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
- 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
-/* #define SHA1HANDSOFF * Copies data before messing with it. */
-
-#define SHA1HANDSOFF
-
-#include <stdio.h>
-#include <string.h>
-
-/* for uint32_t */
-#include <stdint.h>
-
-#include "sha1.h"
-
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
- |(rol(block->l[i],8)&0x00FF00FF))
-#elif BYTE_ORDER == BIG_ENDIAN
-#define blk0(i) block->l[i]
-#else
-#error "Endianness not defined!"
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(
- uint32_t state[5],
- const unsigned char buffer[64]
-)
-{
- uint32_t a, b, c, d, e;
-
- typedef union
- {
- unsigned char c[64];
- uint32_t l[16];
- } CHAR64LONG16;
-
-#ifdef SHA1HANDSOFF
- CHAR64LONG16 block[1]; /* use array to appear as a pointer */
-
- memcpy(block, buffer, 64);
-#else
- /* The following had better never be used because it causes the
- * pointer-to-const buffer to be cast into a pointer to non-const.
- * And the result is written through. I threw a "const" in, hoping
- * this will cause a diagnostic.
- */
- CHAR64LONG16 *block = (const CHAR64LONG16 *) buffer;
-#endif
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a, b, c, d, e, 0);
- R0(e, a, b, c, d, 1);
- R0(d, e, a, b, c, 2);
- R0(c, d, e, a, b, 3);
- R0(b, c, d, e, a, 4);
- R0(a, b, c, d, e, 5);
- R0(e, a, b, c, d, 6);
- R0(d, e, a, b, c, 7);
- R0(c, d, e, a, b, 8);
- R0(b, c, d, e, a, 9);
- R0(a, b, c, d, e, 10);
- R0(e, a, b, c, d, 11);
- R0(d, e, a, b, c, 12);
- R0(c, d, e, a, b, 13);
- R0(b, c, d, e, a, 14);
- R0(a, b, c, d, e, 15);
- R1(e, a, b, c, d, 16);
- R1(d, e, a, b, c, 17);
- R1(c, d, e, a, b, 18);
- R1(b, c, d, e, a, 19);
- R2(a, b, c, d, e, 20);
- R2(e, a, b, c, d, 21);
- R2(d, e, a, b, c, 22);
- R2(c, d, e, a, b, 23);
- R2(b, c, d, e, a, 24);
- R2(a, b, c, d, e, 25);
- R2(e, a, b, c, d, 26);
- R2(d, e, a, b, c, 27);
- R2(c, d, e, a, b, 28);
- R2(b, c, d, e, a, 29);
- R2(a, b, c, d, e, 30);
- R2(e, a, b, c, d, 31);
- R2(d, e, a, b, c, 32);
- R2(c, d, e, a, b, 33);
- R2(b, c, d, e, a, 34);
- R2(a, b, c, d, e, 35);
- R2(e, a, b, c, d, 36);
- R2(d, e, a, b, c, 37);
- R2(c, d, e, a, b, 38);
- R2(b, c, d, e, a, 39);
- R3(a, b, c, d, e, 40);
- R3(e, a, b, c, d, 41);
- R3(d, e, a, b, c, 42);
- R3(c, d, e, a, b, 43);
- R3(b, c, d, e, a, 44);
- R3(a, b, c, d, e, 45);
- R3(e, a, b, c, d, 46);
- R3(d, e, a, b, c, 47);
- R3(c, d, e, a, b, 48);
- R3(b, c, d, e, a, 49);
- R3(a, b, c, d, e, 50);
- R3(e, a, b, c, d, 51);
- R3(d, e, a, b, c, 52);
- R3(c, d, e, a, b, 53);
- R3(b, c, d, e, a, 54);
- R3(a, b, c, d, e, 55);
- R3(e, a, b, c, d, 56);
- R3(d, e, a, b, c, 57);
- R3(c, d, e, a, b, 58);
- R3(b, c, d, e, a, 59);
- R4(a, b, c, d, e, 60);
- R4(e, a, b, c, d, 61);
- R4(d, e, a, b, c, 62);
- R4(c, d, e, a, b, 63);
- R4(b, c, d, e, a, 64);
- R4(a, b, c, d, e, 65);
- R4(e, a, b, c, d, 66);
- R4(d, e, a, b, c, 67);
- R4(c, d, e, a, b, 68);
- R4(b, c, d, e, a, 69);
- R4(a, b, c, d, e, 70);
- R4(e, a, b, c, d, 71);
- R4(d, e, a, b, c, 72);
- R4(c, d, e, a, b, 73);
- R4(b, c, d, e, a, 74);
- R4(a, b, c, d, e, 75);
- R4(e, a, b, c, d, 76);
- R4(d, e, a, b, c, 77);
- R4(c, d, e, a, b, 78);
- R4(b, c, d, e, a, 79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
-#ifdef SHA1HANDSOFF
- memset(block, '\0', sizeof(block));
-#endif
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void SHA1Init(
- SHA1_CTX * context
-)
-{
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void SHA1Update(
- SHA1_CTX * context,
- const unsigned char *data,
- size_t len
-)
-{
- size_t i;
-
- size_t j;
-
- j = context->count[0];
- if ((context->count[0] += len << 3) < j)
- context->count[1]++;
- context->count[1] += (len >> 29);
- j = (j >> 3) & 63;
- if ((j + len) > 63)
- {
- memcpy(&context->buffer[j], data, (i = 64 - j));
- SHA1Transform(context->state, context->buffer);
- for (; i + 63 < len; i += 64)
- {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else
- i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
-}
-
-
-/* Add padding and return the message digest. */
-
-void SHA1Final(
- unsigned char digest[20],
- SHA1_CTX * context
-)
-{
- unsigned i;
-
- unsigned char finalcount[8];
-
- unsigned char c;
-
-#if 0 /* untested "improvement" by DHR */
- /* Convert context->count to a sequence of bytes
- * in finalcount. Second element first, but
- * big-endian order within element.
- * But we do it all backwards.
- */
- unsigned char *fcp = &finalcount[8];
-
- for (i = 0; i < 2; i++)
- {
- uint32_t t = context->count[i];
-
- int j;
-
- for (j = 0; j < 4; t >>= 8, j++)
- *--fcp = (unsigned char) t}
-#else
- for (i = 0; i < 8; i++)
- {
- finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
- }
-#endif
- c = 0200;
- SHA1Update(context, &c, 1);
- while ((context->count[0] & 504) != 448)
- {
- c = 0000;
- SHA1Update(context, &c, 1);
- }
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++)
- {
- digest[i] = (unsigned char)
- ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
- }
- /* Wipe variables */
- memset(context, '\0', sizeof(*context));
- memset(&finalcount, '\0', sizeof(finalcount));
-}
-
-void SHA1(
- const unsigned char *str,
- size_t len,
- unsigned char *hash_out
-)
-{
- SHA1_CTX ctx;
- size_t ii;
-
- SHA1Init(&ctx);
- for (ii=0; ii<len; ii+=1)
- SHA1Update(&ctx, str + ii, 1);
- SHA1Final(hash_out, &ctx);
-}
diff --git a/src/sha1.h b/src/sha1.h
deleted file mode 100644
index c8e9f68..0000000
--- a/src/sha1.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef SHA1_H
-#define SHA1_H
-
-/*
- SHA-1 in C
- By Steve Reid <steve@edmweb.com>
- 100% Public Domain
- */
-
-#include "stdint.h"
-
-typedef struct
-{
- uint32_t state[5];
- uint32_t count[2];
- unsigned char buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(
- uint32_t state[5],
- const unsigned char buffer[64]
- );
-
-void SHA1Init(
- SHA1_CTX * context
- );
-
-void SHA1Update(
- SHA1_CTX * context,
- const unsigned char *data,
- size_t len
- );
-
-void SHA1Final(
- unsigned char digest[20],
- SHA1_CTX * context
- );
-
-void SHA1(
- const unsigned char *str,
- size_t len,
- unsigned char *hash_out);
-
-#endif /* SHA1_H */
diff --git a/src/sha512.c b/src/sha512.c
deleted file mode 100644
index 8f7c59d..0000000
--- a/src/sha512.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
-
-#include "fixedint.h"
-#include "sha512.h"
-
-/* the K array */
-static const uint64_t K[80] = {
- UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
- UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
- UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
- UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
- UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
- UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
- UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
- UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
- UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
- UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
- UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
- UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
- UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
- UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
- UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
- UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
- UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
- UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
- UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
- UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
- UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
- UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
- UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
- UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
- UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
- UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
- UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
- UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
- UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
- UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
- UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
- UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
- UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
- UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
- UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
- UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
- UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
- UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
- UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
- UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
-};
-
-/* Various logical functions */
-
-#define ROR64c(x, y) \
- ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \
- ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF))
-
-#define STORE64H(x, y) \
- { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
- (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
- (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
- (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
-
-#define LOAD64H(x, y) \
- { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
- (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
- (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
- (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
-
-
-#define Ch(x,y,z) (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) (((x | y) & z) | (x & y))
-#define S(x, n) ROR64c(x, n)
-#define R(x, n) (((x) &UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)n))
-#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
-#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
-#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
-#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
-#ifndef MIN
- #define MIN(x, y) ( ((x)<(y))?(x):(y) )
-#endif
-
-/* compress 1024-bits */
-static int sha512_compress(sha512_context *md, unsigned char *buf)
-{
- uint64_t S[8], W[80], t0, t1;
- int i;
-
- /* copy state into S */
- for (i = 0; i < 8; i++) {
- S[i] = md->state[i];
- }
-
- /* copy the state into 1024-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD64H(W[i], buf + (8*i));
- }
-
- /* fill W[16..79] */
- for (i = 16; i < 80; i++) {
- W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
- }
-
-/* Compress */
- #define RND(a,b,c,d,e,f,g,h,i) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c);\
- d += t0; \
- h = t0 + t1;
-
- for (i = 0; i < 80; i += 8) {
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
- }
-
- #undef RND
-
-
-
- /* feedback */
- for (i = 0; i < 8; i++) {
- md->state[i] = md->state[i] + S[i];
- }
-
- return 0;
-}
-
-
-/**
- Initialize the hash state
- @param md The hash state you wish to initialize
- @return 0 if successful
-*/
-int sha512_init(sha512_context * md) {
- if (md == NULL) return 1;
-
- md->curlen = 0;
- md->length = 0;
- md->state[0] = UINT64_C(0x6a09e667f3bcc908);
- md->state[1] = UINT64_C(0xbb67ae8584caa73b);
- md->state[2] = UINT64_C(0x3c6ef372fe94f82b);
- md->state[3] = UINT64_C(0xa54ff53a5f1d36f1);
- md->state[4] = UINT64_C(0x510e527fade682d1);
- md->state[5] = UINT64_C(0x9b05688c2b3e6c1f);
- md->state[6] = UINT64_C(0x1f83d9abfb41bd6b);
- md->state[7] = UINT64_C(0x5be0cd19137e2179);
- md->num_qwords = 8;
-
- return 0;
-}
-
-/**
- Process a block of memory though the hash
- @param md The hash state
- @param in The data to hash
- @param inlen The length of the data (octets)
- @return 0 if successful
-*/
-int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
-{
- size_t n;
- size_t i;
- int err;
- if (md == NULL) return 1;
- if (in == NULL) return 1;
- if (md->curlen > sizeof(md->buf)) {
- return 1;
- }
- while (inlen > 0) {
- if (md->curlen == 0 && inlen >= 128) {
- if ((err = sha512_compress (md, (unsigned char *)in)) != 0) {
- return err;
- }
- md->length += 128 * 8;
- in += 128;
- inlen -= 128;
- } else {
- n = MIN(inlen, (128 - md->curlen));
-
- for (i = 0; i < n; i++) {
- md->buf[i + md->curlen] = in[i];
- }
-
-
- md->curlen += n;
- in += n;
- inlen -= n;
- if (md->curlen == 128) {
- if ((err = sha512_compress (md, md->buf)) != 0) {
- return err;
- }
- md->length += 8*128;
- md->curlen = 0;
- }
- }
- }
- return 0;
-}
-
-/**
- Terminate the hash to get the digest
- @param md The hash state
- @param out [out] The destination of the hash (64 bytes)
- @return 0 if successful
-*/
-int sha512_final(sha512_context * md, unsigned char *out)
-{
- int i;
-
- if (md == NULL) return 1;
- if (out == NULL) return 1;
-
- if (md->curlen >= sizeof(md->buf)) {
- return 1;
- }
-
- /* increase the length of the message */
- md->length += md->curlen * UINT64_C(8);
-
- /* append the '1' bit */
- md->buf[md->curlen++] = (unsigned char)0x80;
-
- /* if the length is currently above 112 bytes we append zeros
- * then compress. Then we can fall back to padding zeros and length
- * encoding like normal.
- */
- if (md->curlen > 112) {
- while (md->curlen < 128) {
- md->buf[md->curlen++] = (unsigned char)0;
- }
- sha512_compress(md, md->buf);
- md->curlen = 0;
- }
-
- /* pad upto 120 bytes of zeroes
- * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
- * > 2^64 bits of data... :-)
- */
- while (md->curlen < 120) {
- md->buf[md->curlen++] = (unsigned char)0;
- }
-
- /* store length */
- STORE64H(md->length, md->buf+120);
- sha512_compress(md, md->buf);
-
- /* copy output */
- for (i = 0; i < md->num_qwords; i++) {
- STORE64H(md->state[i], out+(8*i));
- }
-
- return 0;
-}
-
-int sha512(const unsigned char *message, size_t message_len, unsigned char *out)
-{
- sha512_context ctx;
- int ret;
- if ((ret = sha512_init(&ctx))) return ret;
- if ((ret = sha512_update(&ctx, message, message_len))) return ret;
- if ((ret = sha512_final(&ctx, out))) return ret;
- return 0;
-}
-
-int sha384_init(sha384_context * md) {
- if (md == NULL) return 1;
-
- md->curlen = 0;
- md->length = 0;
- md->state[0] = UINT64_C(0xcbbb9d5dc1059ed8);
- md->state[1] = UINT64_C(0x629a292a367cd507);
- md->state[2] = UINT64_C(0x9159015a3070dd17);
- md->state[3] = UINT64_C(0x152fecd8f70e5939);
- md->state[4] = UINT64_C(0x67332667ffc00b31);
- md->state[5] = UINT64_C(0x8eb44a8768581511);
- md->state[6] = UINT64_C(0xdb0c2e0d64f98fa7);
- md->state[7] = UINT64_C(0x47b5481dbefa4fa4);
- md->num_qwords = 6;
-
- return 0;
-}
-
-int sha384_final(sha384_context * md, unsigned char* out)
-{
- return sha512_final(md, out);
-}
-
-int sha384_update(sha384_context * md, const unsigned char *in, size_t inlen)
-{
- return sha512_update(md, in, inlen);
-}
-
-int sha384(const unsigned char *message, size_t message_len, unsigned char *out)
-{
- sha384_context ctx;
- int ret;
- if ((ret = sha384_init(&ctx))) return ret;
- if ((ret = sha384_update(&ctx, message, message_len))) return ret;
- if ((ret = sha384_final(&ctx, out))) return ret;
- return 0;
-}
diff --git a/src/sha512.h b/src/sha512.h
deleted file mode 100644
index 72db47b..0000000
--- a/src/sha512.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef SHA512_H
-#define SHA512_H
-
-#include <stddef.h>
-
-#include "fixedint.h"
-
-/* state */
-typedef struct sha512_context_ {
- uint64_t length, state[8];
- size_t curlen;
- unsigned char buf[128];
- int num_qwords;
-} sha512_context;
-
-#define SHA512_DIGEST_LENGTH 64
-
-int sha512_init(sha512_context * md);
-int sha512_final(sha512_context * md, unsigned char *out);
-int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen);
-int sha512(const unsigned char *message, size_t message_len, unsigned char *out);
-
-typedef sha512_context sha384_context;
-
-#define SHA384_DIGEST_LENGTH 48
-
-int sha384_init(sha384_context * md);
-int sha384_final(sha384_context * md, unsigned char *out);
-int sha384_update(sha384_context * md, const unsigned char *in, size_t inlen);
-int sha384(const unsigned char *message, size_t message_len, unsigned char *out);
-
-#endif
diff --git a/src/tss.c b/src/tss.c
deleted file mode 100644
index 99781ef..0000000
--- a/src/tss.c
+++ /dev/null
@@ -1,1794 +0,0 @@
-/*
- * tss.c
- * Functions for communicating with Apple's TSS server
- *
- * Copyright (c) 2010-2013 Martin Szulecki. All Rights Reserved.
- * Copyright (c) 2012 Nikias Bassen. All Rights Reserved.
- * Copyright (c) 2010 Joshua Hill. 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
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <curl/curl.h>
-#include <plist/plist.h>
-
-#include "tss.h"
-#include "img3.h"
-#include "common.h"
-#include "idevicerestore.h"
-
-#include "endianness.h"
-
-#define AUTH_VERSION "973.40.2"
-
-#ifdef WIN32
-#define TSS_CLIENT_VERSION_STRING "libauthinstall_Win-"AUTH_VERSION""
-#else
-#define TSS_CLIENT_VERSION_STRING "libauthinstall-"AUTH_VERSION""
-#endif
-#define ECID_STRSIZE 0x20
-
-typedef struct {
- int length;
- char* content;
-} tss_response;
-
-char* ecid_to_string(uint64_t ecid)
-{
- char* ecid_string = malloc(ECID_STRSIZE);
- memset(ecid_string, '\0', ECID_STRSIZE);
- if (ecid == 0) {
- error("ERROR: Invalid ECID passed.\n");
- return NULL;
- }
- snprintf(ecid_string, ECID_STRSIZE, "%"PRIu64, ecid);
- return ecid_string;
-}
-
-plist_t tss_request_new(plist_t overrides)
-{
- plist_t request = plist_new_dict();
-
- plist_dict_set_item(request, "@HostPlatformInfo",
-#ifdef WIN32
- plist_new_string("windows")
-#else
- plist_new_string("mac")
-#endif
- );
-
- plist_dict_set_item(request, "@VersionInfo", plist_new_string(TSS_CLIENT_VERSION_STRING));
- char* guid = generate_guid();
- if (guid) {
- plist_dict_set_item(request, "@UUID", plist_new_string(guid));
- free(guid);
- }
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return request;
-}
-
-int tss_request_add_local_policy_tags(plist_t request, plist_t parameters)
-{
- plist_dict_set_item(request, "@ApImg4Ticket", plist_new_bool(1));
-
- if (plist_dict_copy_bool(request, parameters, "Ap,LocalBoot", NULL) < 0) {
- error("ERROR: Unable to find required Ap,LocalBoot in parameters\n");
- return -1;
- }
-
- if (plist_dict_copy_item(request, parameters, "Ap,LocalPolicy", NULL) < 0) {
- error("ERROR: Unable to find required Ap,LocalPolicy in parameters\n");
- return -1;
- }
-
- if (plist_dict_copy_data(request, parameters, "Ap,NextStageIM4MHash", NULL) < 0) {
- error("ERROR: Unable to find required Ap,NextStageIM4MHash in parameters\n");
- return -1;
- }
-
- plist_dict_copy_data(request, parameters, "Ap,RecoveryOSPolicyNonceHash", NULL);
- plist_dict_copy_data(request, parameters, "Ap,VolumeUUID", NULL);
- plist_dict_copy_uint(request, parameters, "ApECID", NULL);
- plist_dict_copy_uint(request, parameters, "ApChipID", NULL);
- plist_dict_copy_uint(request, parameters, "ApBoardID", NULL);
- plist_dict_copy_uint(request, parameters, "ApSecurityDomain", NULL);
- plist_dict_copy_data(request, parameters, "ApNonce", NULL);
-
- if (!plist_dict_get_item(request, "ApSecurityMode")) {
- /* copy from parameters if available */
- if (plist_dict_copy_bool(request, parameters, "ApSecurityMode", NULL) < 0) {
- error("ERROR: Unable to find required ApSecurityMode in parameters\n");
- return -1;
- }
- }
- if (!plist_dict_get_item(request, "ApProductionMode")) {
- /* copy from parameters if available */
- if (plist_dict_copy_bool(request, parameters, "ApProductionMode", NULL) < 0) {
- error("ERROR: Unable to find required ApProductionMode in parameters\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity, bool include_manifest)
-{
- plist_t node = NULL;
-
- if (plist_dict_copy_data(parameters, build_identity, "UniqueBuildID", NULL) < 0) {
- error("ERROR: Unable to find UniqueBuildID node\n");
- return -1;
- }
-
- plist_dict_copy_string(parameters, build_identity, "Ap,OSLongVersion", NULL);
-
- if (plist_dict_copy_uint(parameters, build_identity, "ApChipID", NULL) < 0) {;
- error("ERROR: Unable to find ApChipID node\n");
- return -1;
- }
-
- if (plist_dict_copy_uint(parameters, build_identity, "ApBoardID", NULL) < 0) {
- error("ERROR: Unable to find ApBoardID node\n");
- return -1;
- }
-
- plist_dict_copy_uint(parameters, build_identity, "ApSecurityDomain", NULL);
- plist_dict_copy_uint(parameters, build_identity, "BMU,BoardID", NULL);
- plist_dict_copy_uint(parameters, build_identity, "BMU,ChipID", NULL);
-
- if (plist_dict_copy_uint(parameters, build_identity, "BbChipID", NULL) < 0) {
- debug("NOTE: Unable to find BbChipID node\n");
- }
-
- if (plist_dict_copy_data(parameters, build_identity, "BbProvisioningManifestKeyHash", NULL) < 0) {
- debug("NOTE: Unable to find BbProvisioningManifestKeyHash node\n");
- }
-
- if (plist_dict_copy_data(parameters, build_identity, "BbActivationManifestKeyHash", NULL) < 0) {
- debug("NOTE: Unable to find BbActivationManifestKeyHash node\n");
- }
-
- if (plist_dict_copy_data(parameters, build_identity, "BbCalibrationManifestKeyHash", NULL) < 0) {
- debug("NOTE: Unable to find BbCalibrationManifestKeyHash node\n");
- }
-
- if (plist_dict_copy_data(parameters, build_identity, "BbFactoryActivationManifestKeyHash", NULL) < 0) {
- debug("NOTE: Unable to find BbFactoryActivationManifestKeyHash node\n");
- }
-
- if (plist_dict_copy_data(parameters, build_identity, "BbFDRSecurityKeyHash", NULL) < 0) {
- debug("NOTE: Unable to find BbFDRSecurityKeyHash node\n");
- }
-
- /* BbSkeyId - Used by XMM 6180/GSM */
- if (plist_dict_copy_data(parameters, build_identity, "BbSkeyId", NULL) < 0) {
- debug("NOTE: Unable to find BbSkeyId node\n");
- }
-
- /* SE,ChipID - Used for SE firmware request */
- plist_dict_copy_uint(parameters, build_identity, "SE,ChipID", NULL);
-
- /* Savage,ChipID - Used for Savage firmware request */
- plist_dict_copy_uint(parameters, build_identity, "Savage,ChipID", NULL);
-
- /* add Savage,PatchEpoch - Used for Savage firmware request */
- plist_dict_copy_uint(parameters, build_identity, "Savage,PatchEpoch", NULL);
-
- /* Yonkers,BoardID - Used for Yonkers firmware request */
- plist_dict_copy_uint(parameters, build_identity, "Yonkers,BoardID", NULL);
-
- /* Yonkers,ChipID - Used for Yonkers firmware request */
- plist_dict_copy_uint(parameters, build_identity, "Yonkers,ChipID", NULL);
-
- /* add Yonkers,PatchEpoch - Used for Yonkers firmware request */
- plist_dict_copy_uint(parameters, build_identity, "Yonkers,PatchEpoch", NULL);
-
- plist_dict_copy_uint(parameters, build_identity, "Rap,BoardID", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Rap,ChipID", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Rap,SecurityDomain", NULL);
-
- plist_dict_copy_uint(parameters, build_identity, "Baobab,BoardID", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Baobab,ChipID", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Baobab,ManifestEpoch", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Baobab,SecurityDomain", NULL);
-
- plist_dict_copy_uint(parameters, build_identity, "eUICC,ChipID", NULL);
-
- plist_dict_copy_uint(parameters, build_identity, "NeRDEpoch", NULL);
- plist_dict_copy_data(parameters, build_identity, "PearlCertificationRootPub", NULL);
-
- plist_dict_copy_uint(parameters, build_identity, "Timer,BoardID,1", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Timer,BoardID,2", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Timer,ChipID,1", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Timer,ChipID,2", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Timer,SecurityDomain,1", NULL);
- plist_dict_copy_uint(parameters, build_identity, "Timer,SecurityDomain,2", NULL);
-
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,ChipID", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,Type", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,SubType", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,ProductClass", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,UseProductClass", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,NonceDomain", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,Version", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,PreauthorizationVersion", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,FakeRoot", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,SystemOS", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,SystemVolume", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,SystemTrustCache", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,AppOS", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,AppVolume", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,AppTrustCache", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,MobileAssetBrainOS", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,MobileAssetBrainVolume", NULL);
- plist_dict_copy_item(parameters, build_identity, "Cryptex1,MobileAssetBrainTrustCache", NULL);
-
- plist_dict_copy_item(parameters, build_identity, "USBPortController1,BoardID", NULL);
- plist_dict_copy_item(parameters, build_identity, "USBPortController1,ChipID", NULL);
- plist_dict_copy_item(parameters, build_identity, "USBPortController1,SecurityDomain", NULL);
-
- node = plist_dict_get_item(build_identity, "Info");
- if (node) {
- plist_dict_copy_bool(parameters, node, "RequiresUIDMode", NULL);
- }
-
- if (include_manifest) {
- /* add build identity manifest dictionary */
- node = plist_dict_get_item(build_identity, "Manifest");
- if (!node || plist_get_node_type(node) != PLIST_DICT) {
- error("ERROR: Unable to find Manifest node\n");
- return -1;
- }
- plist_dict_set_item(parameters, "Manifest", plist_copy(node));
- }
-
- return 0;
-}
-
-int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters)
-{
- if (!parameters) {
- error("ERROR: Missing required AP parameters\n");
- return -1;
- }
-
- plist_dict_copy_string(request, parameters, "Ap,OSLongVersion", NULL);
-
- if (plist_dict_copy_data(request, parameters, "ApNonce", NULL) < 0) {
- error("ERROR: Unable to find required ApNonce in parameters\n");
- return -1;
- }
-
- plist_dict_set_item(request, "@ApImg4Ticket", plist_new_bool(1));
-
- if (!plist_dict_get_item(request, "ApSecurityMode")) {
- /* copy from parameters if available */
- if (plist_dict_copy_bool(request, parameters, "ApSecurityMode", NULL) < 0) {
- error("ERROR: Unable to find required ApSecurityMode in parameters\n");
- return -1;
- }
- }
- if (!plist_dict_get_item(request, "ApProductionMode")) {
- /* ApProductionMode */
- if (plist_dict_copy_bool(request, parameters, "ApProductionMode", NULL) < 0) {
- error("ERROR: Unable to find required ApProductionMode in parameters\n");
- return -1;
- }
- }
-
- plist_dict_copy_data(request, parameters, "SepNonce", "ApSepNonce");
- plist_dict_copy_uint(request, parameters, "NeRDEpoch", NULL);
- plist_dict_copy_data(request, parameters, "PearlCertificationRootPub", NULL);
-
- if (plist_dict_get_item(parameters, "UID_MODE")) {
- plist_dict_copy_item(request, parameters, "UID_MODE", NULL);
- } else if (plist_dict_get_bool(parameters, "RequiresUIDMode")) {
- // The logic here is missing why this value is expected to be 'false'
- plist_dict_set_item(request, "UID_MODE", plist_new_bool(0));
- }
-
- // FIXME: I didn't understand yet when this value is set, so for now we use a workaround
- if (plist_dict_get_item(parameters, "ApSikaFuse")) {
- plist_dict_copy_item(request, parameters, "Ap,SikaFuse", "ApSikaFuse");
- } else if (plist_dict_get_bool(parameters, "RequiresUIDMode")) {
- // Workaround: We have only seen Ap,SikaFuse together with UID_MODE
- plist_dict_set_item(request, "Ap,SikaFuse", plist_new_int(0));
- }
-
- return 0;
-}
-
-int tss_request_add_ap_img3_tags(plist_t request, plist_t parameters)
-{
- if (!parameters) {
- error("ERROR: Missing required AP parameters\n");
- return -1;
- }
-
- if (plist_dict_copy_data(request, parameters, "ApNonce", NULL) < 0) {
- error("WARNING: Unable to find ApNonce in parameters\n");
- }
-
- plist_dict_set_item(request, "@APTicket", plist_new_bool(1));
-
- if (plist_dict_copy_uint(request, parameters, "ApBoardID", NULL) < 0) {
- error("ERROR: Unable to find required ApBoardID in request\n");
- return -1;
- }
-
- if (plist_dict_copy_uint(request, parameters, "ApChipID", NULL) < 0) {
- error("ERROR: Unable to find required ApChipID in request\n");
- return -1;
- }
-
- if (plist_dict_copy_uint(request, parameters, "ApSecurityDomain", NULL) < 0) {
- error("ERROR: Unable to find required ApSecurityDomain in request\n");
- return -1;
- }
-
- if (plist_dict_copy_bool(request, parameters, "ApProductionMode", NULL) < 0) {
- error("ERROR: Unable to find required ApProductionMode in parameters\n");
- return -1;
- }
-
- return 0;
-}
-
-int tss_request_add_common_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_dict_copy_uint(request, parameters, "ApECID", NULL);
- plist_dict_copy_data(request, parameters, "UniqueBuildID", NULL);
- plist_dict_copy_uint(request, parameters, "ApChipID", NULL);
- plist_dict_copy_uint(request, parameters, "ApBoardID", NULL);
- plist_dict_copy_uint(request, parameters, "ApSecurityDomain", NULL);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-static void tss_entry_apply_restore_request_rules(plist_t tss_entry, plist_t parameters, plist_t rules)
-{
- if (!tss_entry || !rules) {
- return;
- }
- if (plist_get_node_type(tss_entry) != PLIST_DICT) {
- return;
- }
- if (plist_get_node_type(rules) != PLIST_ARRAY) {
- return;
- }
-
- uint32_t i;
- for (i = 0; i < plist_array_get_size(rules); i++) {
- plist_t rule = plist_array_get_item(rules, i);
- plist_t conditions = plist_dict_get_item(rule, "Conditions");
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(conditions, &iter);
- char* key = NULL;
- plist_t value = NULL;
- plist_t value2 = NULL;
- int conditions_fulfilled = 1;
- while (conditions_fulfilled) {
- plist_dict_next_item(conditions, iter, &key, &value);
- if (key == NULL)
- break;
- if (!strcmp(key, "ApRawProductionMode")) {
- value2 = plist_dict_get_item(parameters, "ApProductionMode");
- } else if (!strcmp(key, "ApCurrentProductionMode")) {
- value2 = plist_dict_get_item(parameters, "ApProductionMode");
- } else if (!strcmp(key, "ApRawSecurityMode")) {
- value2 = plist_dict_get_item(parameters, "ApSecurityMode");
- } else if (!strcmp(key, "ApRequiresImage4")) {
- value2 = plist_dict_get_item(parameters, "ApSupportsImg4");
- } else if (!strcmp(key, "ApDemotionPolicyOverride")) {
- value2 = plist_dict_get_item(parameters, "DemotionPolicy");
- } else if (!strcmp(key, "ApInRomDFU")) {
- value2 = plist_dict_get_item(parameters, "ApInRomDFU");
- } else {
- error("WARNING: Unhandled condition '%s' while parsing RestoreRequestRules\n", key);
- value2 = NULL;
- }
- if (value2) {
- conditions_fulfilled = plist_compare_node_value(value, value2);
- } else {
- conditions_fulfilled = 0;
- }
- free(key);
- }
- free(iter);
- iter = NULL;
-
- if (!conditions_fulfilled) {
- continue;
- }
-
- plist_t actions = plist_dict_get_item(rule, "Actions");
- plist_dict_new_iter(actions, &iter);
- while (1) {
- plist_dict_next_item(actions, iter, &key, &value);
- if (key == NULL)
- break;
- uint8_t bv = 255;
- plist_get_bool_val(value, &bv);
- if (bv != 255) {
- value2 = plist_dict_get_item(tss_entry, key);
- if (value2) {
- plist_dict_remove_item(tss_entry, key);
- }
- debug("DEBUG: Adding %s=%s to TSS entry\n", key, (bv) ? "true" : "false");
- plist_dict_set_item(tss_entry, key, plist_new_bool(bv));
- }
- free(key);
- }
- }
-}
-
-int tss_request_add_ap_recovery_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- /* loop over components from build manifest */
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: Unable to find restore manifest\n");
- return -1;
- }
-
- /* add components to request */
- char* key = NULL;
- plist_t manifest_entry = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (1) {
- free(key);
- key = NULL;
- plist_dict_next_item(manifest_node, iter, &key, &manifest_entry);
- if (key == NULL)
- break;
- if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) {
- error("ERROR: Unable to fetch BuildManifest entry\n");
- free(key);
- return -1;
- }
-
- /* do not populate BaseBandFirmware, only in basebaseband request */
- if ((strcmp(key, "BasebandFirmware") == 0)) {
- continue;
- }
-
- // Compared to ac2, not needed for RecoveryOSRootTicket
- if ((strcmp(key, "SE,UpdatePayload") == 0)) {
- continue;
- }
- if ((strcmp(key, "BaseSystem") == 0)) {
- continue;
- }
- if ((strcmp(key, "ANS") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,AudioBootChime") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,CIO") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,RestoreCIO") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,RestoreTMU") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,TMU") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,rOSLogo1") == 0)) {
- continue;
- }
- if ((strcmp(key, "Ap,rOSLogo2") == 0)) {
- continue;
- }
- if ((strcmp(key, "AppleLogo") == 0)) {
- continue;
- }
- if ((strcmp(key, "DCP") == 0)) {
- continue;
- }
- if ((strcmp(key, "LLB") == 0)) {
- continue;
- }
- if ((strcmp(key, "RecoveryMode") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreANS") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreDCP") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreDeviceTree") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreKernelCache") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreLogo") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreRamDisk") == 0)) {
- continue;
- }
- if ((strcmp(key, "RestoreSEP") == 0)) {
- continue;
- }
- if ((strcmp(key, "SEP") == 0)) {
- continue;
- }
- if ((strcmp(key, "ftap") == 0)) {
- continue;
- }
- if ((strcmp(key, "ftsp") == 0)) {
- continue;
- }
- if ((strcmp(key, "iBEC") == 0)) {
- continue;
- }
- if ((strcmp(key, "iBSS") == 0)) {
- continue;
- }
- if ((strcmp(key, "rfta") == 0)) {
- continue;
- }
- if ((strcmp(key, "rfts") == 0)) {
- continue;
- }
-
- /* FIXME: only used with diagnostics firmware */
- if (strcmp(key, "Diags") == 0) {
- continue;
- }
-
- plist_t info_dict = plist_dict_get_item(manifest_entry, "Info");
- if (!info_dict) {
- continue;
- }
-
- if (plist_dict_get_bool(parameters, "_OnlyFWComponents")) {
- if (!plist_dict_get_bool(manifest_entry, "Trusted")) {
- debug("DEBUG: %s: Skipping '%s' as it is not trusted\n", __func__, key);
- continue;
- }
-
- if (!plist_dict_get_bool(info_dict, "IsFirmwarePayload")
- && !plist_dict_get_bool(info_dict, "IsSecondaryFirmwarePayload")
- && !plist_dict_get_bool(info_dict, "IsFUDFirmware")
- && !plist_dict_get_bool(info_dict, "IsLoadedByiBoot")
- && !plist_dict_get_bool(info_dict, "IsEarlyAccessFirmware")
- && !plist_dict_get_bool(info_dict, "IsiBootEANFirmware")
- && !plist_dict_get_bool(info_dict, "IsiBootNonEssentialFirmware"))
- {
- debug("DEBUG: %s: Skipping '%s' as it is not a firmware payload\n", __func__, key);
- continue;
- }
- }
-
- /* copy this entry */
- plist_t tss_entry = plist_copy(manifest_entry);
-
- /* remove obsolete Info node */
- plist_dict_remove_item(tss_entry, "Info");
-
- /* handle RestoreRequestRules */
- plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
- if (rules) {
- debug("DEBUG: Applying restore request rules for entry %s\n", key);
- tss_entry_apply_restore_request_rules(tss_entry, parameters, rules);
- }
-
- /* Make sure we have a Digest key for Trusted items even if empty */
- if (plist_dict_get_bool(manifest_entry, "Trusted") && !plist_dict_get_item(manifest_entry, "Digest")) {
- debug("DEBUG: No Digest data, using empty value for entry %s\n", key);
- plist_dict_set_item(tss_entry, "Digest", plist_new_data(NULL, 0));
- }
-
- /* finally add entry to request */
- plist_dict_set_item(request, key, tss_entry);
- }
- free(key);
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- /* loop over components from build manifest */
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: Unable to find restore manifest\n");
- return -1;
- }
-
- /* add components to request */
- char* key = NULL;
- plist_t manifest_entry = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (1) {
- free(key);
- key = NULL;
- plist_dict_next_item(manifest_node, iter, &key, &manifest_entry);
- if (key == NULL)
- break;
- if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) {
- error("ERROR: Unable to fetch BuildManifest entry\n");
- free(key);
- return -1;
- }
-
- /* do not populate BaseBandFirmware, only in basebaseband request */
- if ((strcmp(key, "BasebandFirmware") == 0)) {
- continue;
- }
-
- // Compared to ac2, not needed
- if ((strcmp(key, "SE,UpdatePayload") == 0)) {
- continue;
- }
-
- // Compared to ac2, not needed
- if ((strcmp(key, "BaseSystem") == 0)) {
- continue;
- }
-
- /* FIXME: only used with diagnostics firmware */
- if (strcmp(key, "Diags") == 0) {
- continue;
- }
-
- plist_t info_dict = plist_dict_get_item(manifest_entry, "Info");
- if (!info_dict) {
- continue;
- }
-
- if (plist_dict_get_bool(parameters, "ApSupportsImg4")) {
- if (!plist_dict_get_item(info_dict, "RestoreRequestRules")) {
- debug("DEBUG: %s: Skipping '%s' as it doesn't have RestoreRequestRules\n", __func__, key);
- continue;
- }
- }
-
- int is_fw_payload = plist_dict_get_bool(info_dict, "IsFirmwarePayload")
- || plist_dict_get_bool(info_dict, "IsSecondaryFirmwarePayload")
- || plist_dict_get_bool(info_dict, "IsFUDFirmware")
- || plist_dict_get_bool(info_dict, "IsLoadedByiBoot")
- || plist_dict_get_bool(info_dict, "IsEarlyAccessFirmware")
- || plist_dict_get_bool(info_dict, "IsiBootEANFirmware")
- || plist_dict_get_bool(info_dict, "IsiBootNonEssentialFirmware");
-
- if (plist_dict_get_bool(parameters, "_OnlyFWOrTrustedComponents")) {
- if (!plist_dict_get_bool(manifest_entry, "Trusted") && !is_fw_payload) {
- debug("DEBUG: %s: Skipping '%s' as it is neither firmware payload nor trusted\n", __func__, key);
- continue;
- }
- } else if (plist_dict_get_bool(parameters, "_OnlyFWComponents")) {
- if (!plist_dict_get_bool(manifest_entry, "Trusted")) {
- debug("DEBUG: %s: Skipping '%s' as it is not trusted\n", __func__, key);
- continue;
- }
- if (!is_fw_payload) {
- debug("DEBUG: %s: Skipping '%s' as it is not a firmware payload\n", __func__, key);
- continue;
- }
- }
-
- /* skip components with IsFTAB:true */
- if (plist_dict_get_bool(info_dict, "IsFTAB")) {
- debug("DEBUG: %s: Skipping FTAB component '%s'\n", __func__, key);
- continue;
- }
-
- /* copy this entry */
- plist_t tss_entry = plist_copy(manifest_entry);
-
- /* remove obsolete Info node */
- plist_dict_remove_item(tss_entry, "Info");
-
- /* handle RestoreRequestRules */
- plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
- if (rules) {
- debug("DEBUG: Applying restore request rules for entry %s\n", key);
- tss_entry_apply_restore_request_rules(tss_entry, parameters, rules);
- }
-
- /* Make sure we have a Digest key for Trusted items even if empty */
- if (plist_dict_get_bool(manifest_entry, "Trusted") && !plist_dict_get_item(manifest_entry, "Digest")) {
- debug("DEBUG: No Digest data, using empty value for entry %s\n", key);
- plist_dict_set_item(tss_entry, "Digest", plist_new_data(NULL, 0));
- }
-
- /* finally add entry to request */
- plist_dict_set_item(request, key, tss_entry);
- }
- free(key);
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t node = NULL;
-
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
-
- plist_dict_copy_uint(request, parameters, "BbChipID", NULL);
- plist_dict_copy_data(request, parameters, "BbProvisioningManifestKeyHash", NULL);
- /* BbActivationManifestKeyHash - Used by Qualcomm MDM6610 */
- plist_dict_copy_data(request, parameters, "BbActivationManifestKeyHash", NULL);
- plist_dict_copy_data(request, parameters, "BbCalibrationManifestKeyHash", NULL);
- plist_dict_copy_data(request, parameters, "BbFactoryActivationManifestKeyHash", NULL);
- plist_dict_copy_data(request, parameters, "BbFDRSecurityKeyHash", NULL);
- /* BbSkeyId - Used by XMM 6180/GSM */
- plist_dict_copy_data(request, parameters, "BbSkeyId", NULL);
- plist_dict_copy_data(request, parameters, "BbNonce", NULL);
- plist_dict_copy_uint(request, parameters, "BbGoldCertId", NULL);
-
- uint64_t bb_chip_id = plist_dict_get_uint(request, "BbChipID");
- int32_t bb_cert_id = (int32_t)plist_dict_get_uint(request, "BbGoldCertId");
-
- if (plist_dict_copy_data(request, parameters, "BbSNUM", NULL) < 0) {
- error("ERROR: Unable to find required BbSNUM in parameters\n");
- return -1;
- }
-
- /* BasebandFirmware */
- node = plist_access_path(parameters, 2, "Manifest", "BasebandFirmware");
- if (!node || plist_get_node_type(node) != PLIST_DICT) {
- error("ERROR: Unable to get BasebandFirmware node\n");
- return -1;
- }
- plist_t bbfwdict = plist_copy(node);
- node = NULL;
- if (plist_dict_get_item(bbfwdict, "Info")) {
- plist_dict_remove_item(bbfwdict, "Info");
- }
-
- if (bb_chip_id == 0x68) {
- /* depending on the BasebandCertId remove certain nodes */
- if (bb_cert_id == 0x26F3FACC || bb_cert_id == 0x5CF2EC4E || bb_cert_id == 0x8399785A) {
- plist_dict_remove_item(bbfwdict, "PSI2-PartialDigest");
- plist_dict_remove_item(bbfwdict, "RestorePSI2-PartialDigest");
- } else {
- plist_dict_remove_item(bbfwdict, "PSI-PartialDigest");
- plist_dict_remove_item(bbfwdict, "RestorePSI-PartialDigest");
- }
- }
-
- plist_dict_set_item(request, "BasebandFirmware", bbfwdict);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
-
- if (plist_dict_copy_uint(request, parameters, "SE,ChipID", NULL) < 0) {
- error("ERROR: %s: Unable to find required SE,ChipID in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_data(request, parameters, "SE,ID", NULL) < 0) {
- error("ERROR: %s: Unable to find required SE,ID in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_data(request, parameters, "SE,Nonce", NULL) < 0) {
- error("ERROR: %s: Unable to find required SE,Nonce in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_data(request, parameters, "SE,RootKeyIdentifier", NULL) < 0) {
- error("ERROR: %s: Unable to find required SE,RootKeyIdentifier in parameters\n", __func__);
- return -1;
- }
-
- /* 'IsDev' determines whether we have Production or Development */
- uint8_t is_dev = plist_dict_get_bool(parameters, "SE,IsDev");
-
- /* add SE,* components from build manifest to request */
- char* key = NULL;
- plist_t manifest_entry = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (1) {
- free(key);
- key = NULL;
- plist_dict_next_item(manifest_node, iter, &key, &manifest_entry);
- if (key == NULL)
- break;
- if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) {
- error("ERROR: Unable to fetch BuildManifest entry\n");
- free(key);
- return -1;
- }
-
- if (strncmp(key, "SE,", 3)) {
- continue;
- }
-
- /* copy this entry */
- plist_t tss_entry = plist_copy(manifest_entry);
-
- /* remove Info node */
- plist_dict_remove_item(tss_entry, "Info");
-
- /* remove Development or Production key/hash node */
- if (is_dev) {
- if (plist_dict_get_item(tss_entry, "ProductionCMAC"))
- plist_dict_remove_item(tss_entry, "ProductionCMAC");
- if (plist_dict_get_item(tss_entry, "ProductionUpdatePayloadHash"))
- plist_dict_remove_item(tss_entry, "ProductionUpdatePayloadHash");
- } else {
- if (plist_dict_get_item(tss_entry, "DevelopmentCMAC"))
- plist_dict_remove_item(tss_entry, "DevelopmentCMAC");
- if (plist_dict_get_item(tss_entry, "DevelopmentUpdatePayloadHash"))
- plist_dict_remove_item(tss_entry, "DevelopmentUpdatePayloadHash");
- }
-
- /* add entry to request */
- plist_dict_set_item(request, key, tss_entry);
- }
- free(key);
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- /* fallback in case no @SE2,Ticket or @SE,Ticket was provided */
- if (!plist_dict_get_item(request, "@SE2,Ticket") && !plist_dict_get_item(request, "@SE,Ticket")) {
- plist_dict_set_item(request, "@SE,Ticket", plist_new_bool(1));
- }
-
- return 0;
-}
-
-int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name)
-{
- plist_t node = NULL;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the Savage,Ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
- plist_dict_set_item(request, "@Savage,Ticket", plist_new_bool(1));
-
- if (plist_dict_copy_data(request, parameters, "Savage,UID", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,UID in parameters\n", __func__);
- return -1;
- }
-
- /* add SEP */
- node = plist_access_path(manifest_node, 2, "SEP", "Digest");
- if (!node) {
- error("ERROR: Unable to get SEP digest from manifest\n");
- return -1;
- }
- plist_t dict = plist_new_dict();
- plist_dict_set_item(dict, "Digest", plist_copy(node));
- plist_dict_set_item(request, "SEP", dict);
-
- if (plist_dict_copy_uint(request, parameters, "Savage,PatchEpoch", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,PatchEpoch in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_uint(request, parameters, "Savage,ChipID", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,ChipID in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_bool(request, parameters, "Savage,AllowOfflineBoot", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,AllowOfflineBoot in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_bool(request, parameters, "Savage,ReadFWKey", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,ReadFWKey in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_bool(request, parameters, "Savage,ProductionMode", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,ProductionMode in parameters\n", __func__);
- return -1;
- }
-
- const char *comp_name = NULL;
- uint8_t isprod = plist_dict_get_bool(request, "Savage,ProductionMode");
-
- /* get the right component name */
- comp_name = (isprod) ? "Savage,B0-Prod-Patch" : "Savage,B0-Dev-Patch";
- node = plist_dict_get_item(parameters, "Savage,Revision");
- if (node && (plist_get_node_type(node) == PLIST_DATA)) {
- uint64_t savage_rev_len = 0;
- const unsigned char *savage_rev = (const unsigned char*)plist_get_data_ptr(node, &savage_rev_len);
- if (savage_rev_len > 0) {
- if (((savage_rev[0] | 0x10) & 0xF0) == 0x30) {
- comp_name = (isprod) ? "Savage,B2-Prod-Patch" : "Savage,B2-Dev-Patch";
- } else if ((savage_rev[0] & 0xF0) == 0xA0) {
- comp_name = (isprod) ? "Savage,BA-Prod-Patch" : "Savage,BA-Dev-Patch";
- }
- }
- }
-
- /* add Savage,B?-*-Patch */
- node = plist_dict_get_item(manifest_node, comp_name);
- if (!node) {
- error("ERROR: Unable to get %s entry from manifest\n", comp_name);
- return -1;
- }
- dict = plist_copy(node);
- plist_dict_remove_item(dict, "Info");
- plist_dict_set_item(request, comp_name, dict);
-
- if (component_name) {
- *component_name = strdup(comp_name);
- }
-
- if (plist_dict_copy_data(request, parameters, "Savage,Nonce", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,Nonce in parameters\n", __func__);
- return -1;
- }
-
- if (plist_dict_copy_bool(request, parameters, "Savage,ReadECKey", NULL) < 0) {
- error("ERROR: %s: Unable to find required Savage,ReadECKey in parameters\n", __func__);
- return -1;
- }
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name)
-{
- plist_t node = NULL;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the Savage,Ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
- plist_dict_set_item(request, "@Yonkers,Ticket", plist_new_bool(1));
-
- /* add SEP */
- node = plist_access_path(manifest_node, 2, "SEP", "Digest");
- if (!node) {
- error("ERROR: Unable to get SEP digest from manifest\n");
- return -1;
- }
- plist_t dict = plist_new_dict();
- plist_dict_set_item(dict, "Digest", plist_copy(node));
- plist_dict_set_item(request, "SEP", dict);
-
- {
- static const char *keys[] = {"Yonkers,AllowOfflineBoot", "Yonkers,BoardID", "Yonkers,ChipID", "Yonkers,ECID", "Yonkers,Nonce", "Yonkers,PatchEpoch", "Yonkers,ProductionMode", "Yonkers,ReadECKey", "Yonkers,ReadFWKey", };
- int i;
- for (i = 0; i < (int)(sizeof(keys) / sizeof(keys[0])); ++i) {
- node = plist_dict_get_item(parameters, keys[i]);
- if (!node) {
- error("ERROR: %s: Unable to find required %s in parameters\n", __func__, keys[i]);
- }
- plist_dict_set_item(request, keys[i], plist_copy(node));
- node = NULL;
- }
- }
-
- char *comp_name = NULL;
- plist_t comp_node = NULL;
- uint8_t isprod = plist_dict_get_bool(parameters, "Yonkers,ProductionMode");
- uint64_t fabrevision = plist_dict_get_uint(parameters, "Yonkers,FabRevision");
-
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (iter) {
- node = NULL;
- comp_name = NULL;
- plist_dict_next_item(manifest_node, iter, &comp_name, &node);
- if (comp_name == NULL) {
- node = NULL;
- break;
- }
- if (strncmp(comp_name, "Yonkers,", 8) == 0) {
- int target_node = 1;
- plist_t sub_node;
- if ((sub_node = plist_dict_get_item(node, "EPRO")) != NULL && plist_get_node_type(sub_node) == PLIST_BOOLEAN) {
- uint8_t b = 0;
- plist_get_bool_val(sub_node, &b);
- target_node &= ((isprod) ? b : !b);
- }
- if ((sub_node = plist_dict_get_item(node, "FabRevision")) != NULL && plist_get_node_type(sub_node) == PLIST_UINT) {
- uint64_t v = 0;
- plist_get_uint_val(sub_node, &v);
- target_node &= (v == fabrevision);
- }
- if (target_node) {
- comp_node = node;
- break;
- }
- }
- free(comp_name);
- }
- free(iter);
-
- if (comp_name == NULL) {
- error("ERROR: No Yonkers node for %s/%lu\n", (isprod) ? "Production" : "Development", (unsigned long)fabrevision);
- return -1;
- }
-
- /* add Yonkers,SysTopPatch* */
- if (comp_node != NULL) {
- plist_t comp_dict = plist_copy(comp_node);
- plist_dict_remove_item(comp_dict, "Info");
- plist_dict_set_item(request, comp_name, comp_dict);
- }
-
- if (component_name) {
- *component_name = comp_name;
- } else {
- free(comp_name);
- }
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_vinyl_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t node = NULL;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the eUICC,Ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
- plist_dict_set_item(request, "@eUICC,Ticket", plist_new_bool(1));
-
- plist_dict_copy_bool(request, parameters, "eUICC,ApProductionMode", "ApProductionMode");
- plist_dict_copy_uint(request, parameters, "eUICC,ChipID", NULL);
- plist_dict_copy_data(request, parameters, "eUICC,EID", NULL);
- plist_dict_copy_data(request, parameters, "eUICC,RootKeyIdentifier", NULL);
-
- if (!plist_dict_get_item(request, "eUICC,Gold")) {
- plist_t n = plist_access_path(parameters, 2, "Manifest", "eUICC,Gold");
- if (n) {
- plist_t p = plist_new_dict();
- plist_dict_copy_data(p, n, "Digest", NULL);
- plist_dict_set_item(request, "eUICC,Gold", p);
- }
- }
-
- if (!plist_dict_get_item(request, "eUICC,Main")) {
- plist_t n = plist_access_path(parameters, 2, "Manifest", "eUICC,Main");
- if (n) {
- plist_t p = plist_new_dict();
- plist_dict_copy_data(p, n, "Digest", NULL);
- plist_dict_set_item(request, "eUICC,Main", p);
- }
- }
-
- /* set Nonce for eUICC,Gold component */
- node = plist_dict_get_item(parameters, "EUICCGoldNonce");
- if (node) {
- plist_t n = plist_dict_get_item(request, "eUICC,Gold");
- if (n) {
- plist_dict_set_item(n, "Nonce", plist_copy(node));
- }
- }
-
- /* set Nonce for eUICC,Main component */
- node = plist_dict_get_item(parameters, "EUICCMainNonce");
- if (node) {
- plist_t n = plist_dict_get_item(request, "eUICC,Main");
- if (n) {
- plist_dict_set_item(n, "Nonce", plist_copy(node));
- }
- }
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_rose_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t node = NULL;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the Rap,Ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
- plist_dict_set_item(request, "@Rap,Ticket", plist_new_bool(1));
-
- plist_dict_copy_uint(request, parameters, "Rap,BoardID", NULL);
- plist_dict_copy_uint(request, parameters, "Rap,ChipID", NULL);
- plist_dict_copy_uint(request, parameters, "Rap,ECID", NULL);
- plist_dict_copy_data(request, parameters, "Rap,Nonce", NULL);
- plist_dict_copy_bool(request, parameters, "Rap,ProductionMode", NULL);
- plist_dict_copy_uint(request, parameters, "Rap,SecurityDomain", NULL);
- plist_dict_copy_bool(request, parameters, "Rap,SecurityMode", NULL);
- plist_dict_copy_data(request, parameters, "Rap,FdrRootCaDigest", NULL);
-
- char *comp_name = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (iter) {
- node = NULL;
- comp_name = NULL;
- plist_dict_next_item(manifest_node, iter, &comp_name, &node);
- if (comp_name == NULL) {
- node = NULL;
- break;
- }
- if (strncmp(comp_name, "Rap,", 4) == 0) {
- plist_t manifest_entry = plist_copy(node);
-
- /* handle RestoreRequestRules */
- plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
- if (rules) {
- debug("DEBUG: Applying restore request rules for entry %s\n", comp_name);
- tss_entry_apply_restore_request_rules(manifest_entry, parameters, rules);
- }
-
- /* Make sure we have a Digest key for Trusted items even if empty */
- if (plist_dict_get_bool(manifest_entry, "Trusted") && !plist_dict_get_item(manifest_entry, "Digest")) {
- debug("DEBUG: No Digest data, using empty value for entry %s\n", comp_name);
- plist_dict_set_item(manifest_entry, "Digest", plist_new_data(NULL, 0));
- }
-
- plist_dict_remove_item(manifest_entry, "Info");
-
- /* finally add entry to request */
- plist_dict_set_item(request, comp_name, manifest_entry);
- }
- free(comp_name);
- }
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_veridian_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t node = NULL;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the BMU,Ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
- plist_dict_set_item(request, "@BMU,Ticket", plist_new_bool(1));
-
- plist_dict_copy_uint(request, parameters, "BMU,BoardID", NULL);
- plist_dict_copy_uint(request, parameters, "BMU,ChipID", "ChipID");
- plist_dict_copy_data(request, parameters, "BMU,Nonce", "Nonce");
- plist_dict_copy_bool(request, parameters, "BMU,ProductionMode", "ProductionMode");
- plist_dict_copy_uint(request, parameters, "BMU,UniqueID", "UniqueID");
-
- char *comp_name = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (iter) {
- node = NULL;
- comp_name = NULL;
- plist_dict_next_item(manifest_node, iter, &comp_name, &node);
- if (comp_name == NULL) {
- node = NULL;
- break;
- }
- if (strncmp(comp_name, "BMU,", 4) == 0) {
- plist_t manifest_entry = plist_copy(node);
-
- /* handle RestoreRequestRules */
- plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
- if (rules) {
- debug("DEBUG: Applying restore request rules for entry %s\n", comp_name);
- tss_entry_apply_restore_request_rules(manifest_entry, parameters, rules);
- }
-
- /* Make sure we have a Digest key for Trusted items even if empty */
- if (plist_dict_get_bool(manifest_entry, "Trusted") && !plist_dict_get_item(manifest_entry, "Digest")) {
- debug("DEBUG: No Digest data, using empty value for entry %s\n", comp_name);
- plist_dict_set_item(manifest_entry, "Digest", plist_new_data(NULL, 0));
- }
-
- plist_dict_remove_item(manifest_entry, "Info");
-
- /* finally add entry to request */
- plist_dict_set_item(request, comp_name, manifest_entry);
- }
- free(comp_name);
- }
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_tcon_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t node = NULL;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the Baobab,Ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
- plist_dict_set_item(request, "@Baobab,Ticket", plist_new_bool(1));
-
- plist_dict_copy_uint(request, parameters, "Baobab,BoardID", NULL);
- plist_dict_copy_uint(request, parameters, "Baobab,ChipID", NULL);
- plist_dict_copy_data(request, parameters, "Baobab,ECID", NULL);
- plist_dict_copy_uint(request, parameters, "Baobab,Life", NULL);
- plist_dict_copy_uint(request, parameters, "Baobab,ManifestEpoch", NULL);
- plist_dict_copy_bool(request, parameters, "Baobab,ProductionMode", NULL);
- plist_dict_copy_uint(request, parameters, "Baobab,SecurityDomain", NULL);
- plist_dict_copy_data(request, parameters, "Baobab,UpdateNonce", NULL);
-
- uint8_t isprod = plist_dict_get_bool(parameters, "Baobab,ProductionMode");
-
- char *comp_name = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (iter) {
- node = NULL;
- comp_name = NULL;
- plist_dict_next_item(manifest_node, iter, &comp_name, &node);
- if (comp_name == NULL) {
- node = NULL;
- break;
- }
- if (strncmp(comp_name, "Baobab,", 7) == 0) {
- plist_t manifest_entry = plist_copy(node);
-
- plist_dict_remove_item(manifest_entry, "Info");
- plist_dict_set_item(manifest_entry, "EPRO", plist_new_bool(isprod));
-
- /* finally add entry to request */
- plist_dict_set_item(request, comp_name, manifest_entry);
- }
- free(comp_name);
- }
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
- return 0;
-}
-
-int tss_request_add_timer_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- plist_t node = NULL;
- uint32_t tag = 0;
-
- plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
- if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
- error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
- return -1;
- }
-
- /* add tags indicating we want to get the Timer ticket */
- plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
-
- node = plist_dict_get_item(parameters, "TicketName");
- if (!node) {
- error("ERROR: %s: Missing TicketName\n", __func__);
- return -1;
- }
- char key[64];
- sprintf(key, "@%s", plist_get_string_ptr(node, NULL));
-
- plist_dict_set_item(request, key, plist_new_bool(1));
-
- tag = (uint32_t)plist_dict_get_uint(parameters, "TagNumber");
-
- sprintf(key, "Timer,BoardID,%u", tag);
- plist_dict_copy_uint(request, parameters, key, NULL);
-
- sprintf(key, "Timer,ChipID,%u", tag);
- plist_dict_copy_uint(request, parameters, key, NULL);
-
- sprintf(key, "Timer,SecurityDomain,%u", tag);
- plist_dict_copy_uint(request, parameters, key, NULL);
-
- sprintf(key, "Timer,SecurityMode,%u", tag);
- plist_dict_copy_bool(request, parameters, key, NULL);
-
- sprintf(key, "Timer,ProductionMode,%u", tag);
- plist_dict_copy_bool(request, parameters, key, NULL);
-
- sprintf(key, "Timer,ECID,%u", tag);
- plist_dict_copy_uint(request, parameters, key, NULL);
-
- sprintf(key, "Timer,Nonce,%u", tag);
- plist_dict_copy_data(request, parameters, key, NULL);
-
- char *comp_name = NULL;
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(manifest_node, &iter);
- while (iter) {
- node = NULL;
- comp_name = NULL;
- plist_dict_next_item(manifest_node, iter, &comp_name, &node);
- if (comp_name == NULL) {
- node = NULL;
- break;
- }
- if (!strncmp(comp_name, "Timer,", 6)) {
- plist_t manifest_entry = plist_copy(node);
-
- /* handle RestoreRequestRules */
- plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
- if (rules) {
- debug("DEBUG: Applying restore request rules for entry %s\n", comp_name);
- tss_entry_apply_restore_request_rules(manifest_entry, parameters, rules);
- }
-
- /* Make sure we have a Digest key for Trusted items even if empty */
- if (plist_dict_get_bool(manifest_entry, "Trusted") && !plist_dict_get_item(manifest_entry, "Digest")) {
- debug("DEBUG: No Digest data, using empty value for entry %s\n", comp_name);
- plist_dict_set_item(manifest_entry, "Digest", plist_new_data(NULL, 0));
- }
-
- plist_dict_remove_item(manifest_entry, "Info");
-
- /* finally add entry to request */
- plist_dict_set_item(request, comp_name, manifest_entry);
- }
- free(comp_name);
- }
- free(iter);
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-int tss_request_add_cryptex_tags(plist_t request, plist_t parameters, plist_t overrides)
-{
- tss_request_add_common_tags(request, parameters, NULL);
-
- if (plist_dict_get_item(parameters, "Ap,LocalPolicy")) {
- /* Cryptex1LocalPolicy */
- tss_request_add_local_policy_tags(request, parameters);
- plist_dict_copy_data(request, parameters, "Ap,NextStageCryptex1IM4MHash", NULL);
- } else {
- /* Cryptex1 */
- plist_dict_set_item(request, "@Cryptex1,Ticket", plist_new_bool(1));
-
- plist_dict_copy_bool(request, parameters, "ApSecurityMode", NULL);
- plist_dict_copy_bool(request, parameters, "ApProductionMode", NULL);
-
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(parameters, &iter);
- plist_t value = NULL;
- while (1) {
- char *key = NULL;
- plist_dict_next_item(parameters, iter, &key, &value);
- if (key == NULL)
- break;
- if (strncmp(key, "Cryptex1", 8) == 0) {
- plist_dict_set_item(request, key, plist_copy(value));
- }
- free(key);
- }
- }
-
- /* apply overrides */
- if (overrides) {
- plist_dict_merge(&request, overrides);
- }
-
- return 0;
-}
-
-static size_t tss_write_callback(char* data, size_t size, size_t nmemb, tss_response* response)
-{
- size_t total = size * nmemb;
- if (total != 0) {
- response->content = realloc(response->content, response->length + total + 1);
- memcpy(response->content + response->length, data, total);
- response->content[response->length + total] = '\0';
- response->length += total;
- }
-
- return total;
-}
-
-plist_t tss_request_send(plist_t tss_request, const char* server_url_string)
-{
- if (idevicerestore_debug) {
- debug_plist(tss_request);
- }
-
- char* request = NULL;
- int status_code = -1;
- int retry = 0;
- int max_retries = 15;
- unsigned int size = 0;
- char curl_error_message[CURL_ERROR_SIZE];
-
- const char* urls[6] = {
- "https://gs.apple.com/TSS/controller?action=2",
- "https://17.171.36.30/TSS/controller?action=2",
- "https://17.151.36.30/TSS/controller?action=2",
- "http://gs.apple.com/TSS/controller?action=2",
- "http://17.171.36.30/TSS/controller?action=2",
- "http://17.151.36.30/TSS/controller?action=2"
- };
-
- plist_to_xml(tss_request, &request, &size);
-
- tss_response* response = NULL;
- memset(curl_error_message, '\0', CURL_ERROR_SIZE);
-
- while (retry++ < max_retries) {
- response = NULL;
- CURL* handle = curl_easy_init();
- if (handle == NULL) {
- break;
- }
- struct curl_slist* header = NULL;
- header = curl_slist_append(header, "Cache-Control: no-cache");
- header = curl_slist_append(header, "Content-type: text/xml; charset=\"utf-8\"");
- header = curl_slist_append(header, "Expect:");
-
- response = malloc(sizeof(tss_response));
- if (response == NULL) {
- fprintf(stderr, "Unable to allocate sufficient memory\n");
- return NULL;
- }
-
- response->length = 0;
- response->content = malloc(1);
- response->content[0] = '\0';
-
- /* disable SSL verification to allow download from untrusted https locations */
- curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
-
- curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, curl_error_message);
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, (curl_write_callback)&tss_write_callback);
- curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
- curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header);
- curl_easy_setopt(handle, CURLOPT_POSTFIELDS, request);
- curl_easy_setopt(handle, CURLOPT_USERAGENT, USER_AGENT_STRING);
- curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, strlen(request));
- if (server_url_string) {
- curl_easy_setopt(handle, CURLOPT_URL, server_url_string);
- info("Request URL set to %s\n", server_url_string);
- } else {
- int url_index = (retry - 1) % 6;
- curl_easy_setopt(handle, CURLOPT_URL, urls[url_index]);
- info("Request URL set to %s\n", urls[url_index]);
- }
-
- info("Sending TSS request attempt %d... ", retry);
-
- curl_easy_perform(handle);
- curl_slist_free_all(header);
- curl_easy_cleanup(handle);
-
- if (strstr(response->content, "MESSAGE=SUCCESS")) {
- status_code = 0;
- info("response successfully received\n");
- break;
- }
-
- if (response->length > 0) {
- error("TSS server returned: %s\n", response->content);
- }
-
- char* status = strstr(response->content, "STATUS=");
- if (status) {
- sscanf(status+7, "%d&%*s", &status_code);
- }
- if (status_code == -1) {
- error("%s\n", curl_error_message);
- // no status code in response. retry
- free(response->content);
- free(response);
- response = NULL;
- sleep(2);
- continue;
- } else if (status_code == 8) {
- // server error (invalid bb request?)
- break;
- } else if (status_code == 49) {
- // server error (invalid bb data, e.g. BbSNUM?)
- break;
- } else if (status_code == 69 || status_code == 94) {
- // This device isn't eligible for the requested build.
- break;
- } else if (status_code == 100) {
- // server error, most likely the request was malformed
- break;
- } else if (status_code == 126) {
- // An internal error occured, most likely the request was malformed
- break;
- } else {
- error("ERROR: tss_send_request: Unhandled status code %d\n", status_code);
- }
- }
-
- if (status_code != 0) {
- if (response && strstr(response->content, "MESSAGE=") != NULL) {
- char* message = strstr(response->content, "MESSAGE=") + strlen("MESSAGE=");
- error("ERROR: TSS request failed (status=%d, message=%s)\n", status_code, message);
- } else {
- error("ERROR: TSS request failed: %s (status=%d)\n", curl_error_message, status_code);
- }
- free(request);
- if (response) free(response->content);
- if (response) free(response);
- return NULL;
- }
-
- char* tss_data = strstr(response->content, "<?xml");
- if (tss_data == NULL) {
- error("ERROR: Incorrectly formatted TSS response\n");
- free(request);
- free(response->content);
- free(response);
- return NULL;
- }
-
- uint32_t tss_size = 0;
- plist_t tss_response = NULL;
- tss_size = response->length - (tss_data - response->content);
- plist_from_xml(tss_data, tss_size, &tss_response);
- free(response->content);
- free(response);
-
- if (idevicerestore_debug) {
- debug_plist(tss_response);
- }
-
- free(request);
-
- return tss_response;
-}
-
-static int tss_response_get_data_by_key(plist_t response, const char* name, unsigned char** buffer, unsigned int* length)
-{
- plist_t node = plist_dict_get_item(response, name);
- if (!node || plist_get_node_type(node) != PLIST_DATA) {
- debug("DEBUG: %s: No entry '%s' in TSS response\n", __func__, name);
- return -1;
- }
-
- char* data = NULL;
- uint64_t len = 0;
- plist_get_data_val(node, &data, &len);
- if (data) {
- *length = (unsigned int)len;
- *buffer = (unsigned char*)data;
- return 0;
- } else {
- error("ERROR: Unable to get %s data from TSS response\n", name);
- return -1;
- }
-}
-
-int tss_response_get_ap_img4_ticket(plist_t response, unsigned char** ticket, unsigned int* length)
-{
- return tss_response_get_data_by_key(response, "ApImg4Ticket", ticket, length);
-}
-
-int tss_response_get_ap_ticket(plist_t response, unsigned char** ticket, unsigned int* length)
-{
- return tss_response_get_data_by_key(response, "APTicket", ticket, length);
-}
-
-int tss_response_get_baseband_ticket(plist_t response, unsigned char** ticket, unsigned int* length)
-{
- return tss_response_get_data_by_key(response, "BBTicket", ticket, length);
-}
-
-int tss_response_get_path_by_entry(plist_t response, const char* entry, char** path)
-{
- char* path_string = NULL;
- plist_t path_node = NULL;
- plist_t entry_node = NULL;
-
- *path = NULL;
-
- entry_node = plist_dict_get_item(response, entry);
- if (!entry_node || plist_get_node_type(entry_node) != PLIST_DICT) {
- debug("DEBUG: %s: No entry '%s' in TSS response\n", __func__, entry);
- return -1;
- }
-
- path_node = plist_dict_get_item(entry_node, "Path");
- if (!path_node || plist_get_node_type(path_node) != PLIST_STRING) {
- debug("NOTE: Unable to find %s path in TSS entry\n", entry);
- return -1;
- }
- plist_get_string_val(path_node, &path_string);
-
- *path = path_string;
- return 0;
-}
-
-int tss_response_get_blob_by_path(plist_t tss, const char* path, unsigned char** blob)
-{
- uint32_t i = 0;
- uint32_t tss_size = 0;
- uint64_t blob_size = 0;
- char* entry_key = NULL;
- char* blob_data = NULL;
- char* entry_path = NULL;
- plist_t tss_entry = NULL;
- plist_t blob_node = NULL;
- plist_t path_node = NULL;
- plist_dict_iter iter = NULL;
-
- *blob = NULL;
-
- plist_dict_new_iter(tss, &iter);
- tss_size = plist_dict_get_size(tss);
- for (i = 0; i < tss_size; i++) {
- plist_dict_next_item(tss, iter, &entry_key, &tss_entry);
- if (entry_key == NULL)
- break;
-
- if (!tss_entry || plist_get_node_type(tss_entry) != PLIST_DICT) {
- continue;
- }
-
- path_node = plist_dict_get_item(tss_entry, "Path");
- if (!path_node || plist_get_node_type(path_node) != PLIST_STRING) {
- error("ERROR: Unable to find TSS path node in entry %s\n", entry_key);
- free(iter);
- return -1;
- }
-
- plist_get_string_val(path_node, &entry_path);
- if (strcmp(path, entry_path) == 0) {
- blob_node = plist_dict_get_item(tss_entry, "Blob");
- if (!blob_node || plist_get_node_type(blob_node) != PLIST_DATA) {
- error("ERROR: Unable to find TSS blob node in entry %s\n", entry_key);
- free(iter);
- return -1;
- }
- plist_get_data_val(blob_node, &blob_data, &blob_size);
- break;
- }
-
- free(entry_key);
- }
- free(iter);
-
- if (blob_data == NULL || blob_size <= 0) {
- return -1;
- }
-
- *blob = (unsigned char*)blob_data;
- return 0;
-}
-
-int tss_response_get_blob_by_entry(plist_t response, const char* entry, unsigned char** blob)
-{
- uint64_t blob_size = 0;
- char* blob_data = NULL;
- plist_t blob_node = NULL;
- plist_t tss_entry = NULL;
-
- *blob = NULL;
-
- tss_entry = plist_dict_get_item(response, entry);
- if (!tss_entry || plist_get_node_type(tss_entry) != PLIST_DICT) {
- debug("DEBUG: %s: No entry '%s' in TSS response\n", __func__, entry);
- return -1;
- }
-
- blob_node = plist_dict_get_item(tss_entry, "Blob");
- if (!blob_node || plist_get_node_type(blob_node) != PLIST_DATA) {
- error("ERROR: Unable to find blob in %s entry\n", entry);
- return -1;
- }
- plist_get_data_val(blob_node, &blob_data, &blob_size);
-
- *blob = (unsigned char*)blob_data;
- return 0;
-}
diff --git a/src/tss.h b/src/tss.h
deleted file mode 100644
index 8af2fcc..0000000
--- a/src/tss.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * tss.h
- * Definitions for communicating with Apple's TSS server.
- *
- * Copyright (c) 2013 Martin Szulecki. All Rights Reserved.
- * Copyright (c) 2012 Nikias Bassen. All Rights Reserved.
- * Copyright (c) 2010 Joshua Hill. 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
- */
-
-#ifndef IDEVICERESTORE_TSS_H
-#define IDEVICERESTORE_TSS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <plist/plist.h>
-#include <stdbool.h>
-
-/* parameters */
-int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity, bool include_manifest);
-
-/* request */
-plist_t tss_request_new(plist_t overrides);
-
-int tss_request_add_local_policy_tags(plist_t request, plist_t parameters);
-int tss_request_add_common_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_ap_recovery_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name);
-int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name);
-int tss_request_add_vinyl_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_rose_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_veridian_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_tcon_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_timer_tags(plist_t request, plist_t parameters, plist_t overrides);
-int tss_request_add_cryptex_tags(plist_t request, plist_t parameters, plist_t overrides);
-
-int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters);
-int tss_request_add_ap_img3_tags(plist_t request, plist_t parameters);
-
-/* i/o */
-plist_t tss_request_send(plist_t request, const char* server_url_string);
-
-/* response */
-int tss_response_get_ap_img4_ticket(plist_t response, unsigned char** ticket, unsigned int* length);
-int tss_response_get_ap_ticket(plist_t response, unsigned char** ticket, unsigned int* length);
-int tss_response_get_baseband_ticket(plist_t response, unsigned char** ticket, unsigned int* length);
-int tss_response_get_path_by_entry(plist_t response, const char* entry, char** path);
-int tss_response_get_blob_by_path(plist_t response, const char* path, unsigned char** blob);
-int tss_response_get_blob_by_entry(plist_t response, const char* entry, unsigned char** blob);
-
-/* helpers */
-char* ecid_to_string(uint64_t ecid);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif