2
* RabbitSign - Tools for signing TI graphing calculator software
3
* Copyright (C) 2009 Benjamin Moody
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 3 of the
8
* License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#ifndef __RABBITSIGN_H__
20
#define __RABBITSIGN_H__
24
# define rs_snprintf gmp_snprintf
25
# define rs_vsnprintf gmp_vsnprintf
31
# define RS_ATTR_PURE __attribute__((pure))
32
# define RS_ATTR_MALLOC __attribute__((malloc))
33
# define RS_ATTR_UNUSED __attribute__((unused))
34
# define RS_ATTR_PRINTF(f,i) __attribute__((format(printf,f,i)))
37
# define RS_ATTR_MALLOC
38
# define RS_ATTR_UNUSED
39
# define RS_ATTR_PRINTF(f,i)
46
/* Calculator types */
47
typedef enum _RSCalcType {
55
#define rs_calc_is_ti8x(ttt) ((ttt) == RS_CALC_TI73 || (ttt) == RS_CALC_TI83P)
56
#define rs_calc_is_ti9x(ttt) ((ttt) == RS_CALC_TI89 || (ttt) == RS_CALC_TI92P)
59
typedef enum _RSDataType {
66
/* Flags for app signing */
67
typedef enum _RSRepairFlags {
68
RS_IGNORE_ALL_WARNINGS = 1,
69
RS_REMOVE_OLD_SIGNATURE = 2, /* Remove existing signature */
70
RS_FIX_PAGE_COUNT = 4, /* Fix page count header field */
71
RS_FIX_OS_SIZE = 8, /* Fix size in OS header */
72
RS_ZEALOUSLY_PAD_APP = 16 /* Pad application with an extra
76
/* Flags for file input */
77
typedef enum _RSInputFlags {
78
RS_INPUT_BINARY = 32, /* Assume input is raw binary
80
RS_INPUT_SORTED = 64 /* Assume plain hex input is sorted
81
(implicit page switch) */
84
/* Flags for file output */
85
typedef enum _RSOutputFlags {
86
RS_OUTPUT_HEX_ONLY = 128, /* Write plain hex (.app) format */
87
RS_OUTPUT_APPSIGN = 256 /* Write hex data in
88
appsign-compatible format */
91
/* Encryption key structure */
92
typedef struct _RSKey {
93
char* filename; /* Filename */
94
unsigned long id; /* Key ID */
95
mpz_t n; /* Modulus (public key) */
96
mpz_t p; /* First factor */
97
mpz_t q; /* Second factor */
98
mpz_t qinv; /* q^-1 mod p (for Rabin)
99
(rs_sign_rabin() will calculate
100
this based on p and q, if
102
mpz_t d; /* Signing exponent (for RSA)
103
(rs_sign_rsa() will calculate this
104
based on p and q, if needed) */
107
/* Program data structure */
108
typedef struct _RSProgram {
109
char* filename; /* Filename */
110
RSCalcType calctype; /* Calculator type */
111
RSDataType datatype; /* Program data type */
112
unsigned char* data; /* Program data */
113
unsigned long length; /* Length of program data */
114
unsigned long length_a; /* Size of buffer allocated */
116
/* Additional metadata (only used by TI-8x OS) */
117
unsigned char* header; /* OS header */
118
unsigned int header_length; /* Length of OS header */
119
unsigned char* signature; /* OS signature */
120
unsigned int signature_length; /* Length of OS signature */
121
unsigned int* pagenums; /* List of page numbers */
122
int npagenums; /* Number of page numbers */
126
typedef enum _RSStatus {
129
RS_ERR_MISSING_PAGE_COUNT,
130
RS_ERR_MISSING_KEY_ID,
131
RS_ERR_MISSING_DATE_STAMP,
132
RS_ERR_MISSING_PROGRAM_IMAGE,
133
RS_ERR_MISALIGNED_PROGRAM_IMAGE,
134
RS_ERR_INVALID_PROGRAM_DATA,
135
RS_ERR_INVALID_PROGRAM_SIZE,
136
RS_ERR_INCORRECT_PAGE_COUNT,
137
RS_ERR_FINAL_PAGE_TOO_LONG,
138
RS_ERR_FIELD_TOO_SMALL,
140
RS_ERR_CRITICAL = 1000,
142
RS_ERR_OUT_OF_MEMORY,
145
RS_ERR_UNKNOWN_FILE_FORMAT,
146
RS_ERR_UNKNOWN_PROGRAM_TYPE,
147
RS_ERR_MISSING_HEADER,
148
RS_ERR_MISSING_RABIN_SIGNATURE,
149
RS_ERR_MISSING_RSA_SIGNATURE,
150
RS_ERR_INCORRECT_PROGRAM_SIZE,
151
RS_ERR_KEY_NOT_FOUND,
154
RS_ERR_MISSING_PUBLIC_KEY,
155
RS_ERR_MISSING_PRIVATE_KEY,
156
RS_ERR_UNSUITABLE_RABIN_KEY,
157
RS_ERR_UNSUITABLE_RSA_KEY,
159
RS_SIGNATURE_INCORRECT = -1
163
/**** Key handling (keys.c) ****/
165
/* Create a new key. */
166
RSKey* rs_key_new (void) RS_ATTR_MALLOC;
169
void rs_key_free (RSKey* key);
171
/* Read key from a file. */
172
RSStatus rs_read_key_file (RSKey* key, FILE* f,
173
const char* fname, int verify);
175
/* Parse a number written in TI's hexadecimal key format. */
176
RSStatus rs_parse_key_value (mpz_t dest, const char* str);
179
/**** Program data manipulation (program.c) ****/
181
/* Create a new program. */
182
RSProgram* rs_program_new (void) RS_ATTR_MALLOC;
184
/* Create a new program from an existing data buffer. */
185
RSProgram* rs_program_new_with_data (RSCalcType ctype, RSDataType dtype,
186
void* data, unsigned long length,
187
unsigned long buffer_size)
190
/* Free program data. */
191
void rs_program_free (RSProgram* prgm);
193
/* Truncate or extend program. */
194
RSStatus rs_program_set_length (RSProgram* prgm, unsigned long length);
196
/* Add data to the end of the program. */
197
RSStatus rs_program_append_data (RSProgram* prgm, const unsigned char* data,
198
unsigned long length);
201
/**** Search for key file (autokey.c) ****/
203
/* Get key ID for the given program. */
204
unsigned long rs_program_get_key_id (const RSProgram* prgm) RS_ATTR_PURE;
206
/* Find key file for the given ID. */
207
RSStatus rs_key_find_for_id (RSKey* key, unsigned long keyid, int publiconly);
210
/**** Program signing and validation (apps.c) ****/
212
/* Check/fix program header and data. */
213
RSStatus rs_repair_program (RSProgram* prgm, RSRepairFlags flags);
215
/* Add a signature to the program. */
216
RSStatus rs_sign_program (RSProgram* prgm, RSKey* key, int rootnum);
218
/* Validate program signature. */
219
RSStatus rs_validate_program (const RSProgram* prgm, const RSKey* key);
222
/**** TI-73/83+/84+ app signing (app8x.c) ****/
224
/* Check/fix Flash app header and data. */
225
RSStatus rs_repair_ti8x_app (RSProgram* app, RSRepairFlags flags);
227
/* Add a signature to a Flash app. */
228
RSStatus rs_sign_ti8x_app (RSProgram* app, RSKey* key, int rootnum);
230
/* Validate Flash app signature. */
231
RSStatus rs_validate_ti8x_app (const RSProgram* app, const RSKey* key);
234
/**** TI-73/83+/84+ OS signing (os8x.c) ****/
236
/* Check/fix OS header and data. */
237
RSStatus rs_repair_ti8x_os (RSProgram* os, RSRepairFlags flags);
239
/* Add a signature to an OS. */
240
RSStatus rs_sign_ti8x_os (RSProgram* os, RSKey* key);
242
/* Validate OS signature. */
243
RSStatus rs_validate_ti8x_os (const RSProgram* os, const RSKey* key);
246
/**** TI-89/92+ app/OS signing (app9x.c) ****/
248
/* Check/fix Flash app header and data. */
249
RSStatus rs_repair_ti9x_app (RSProgram* app, RSRepairFlags flags);
251
/* Check/fix OS header and data. */
252
RSStatus rs_repair_ti9x_os (RSProgram* app, RSRepairFlags flags);
254
/* Add a signature to a 68k app/OS. */
255
RSStatus rs_sign_ti9x_app (RSProgram* app, RSKey* key);
257
/* Validate app/OS signature. */
258
RSStatus rs_validate_ti9x_app (const RSProgram* app, const RSKey* key);
260
#define rs_sign_ti9x_os rs_sign_ti9x_app
261
#define rs_validate_ti9x_os rs_validate_ti9x_app
264
/**** File input (input.c) ****/
266
/* Read program contents from a file. */
267
RSStatus rs_read_program_file (RSProgram* prgm, FILE* f,
268
const char* fname, RSInputFlags flags);
271
/**** File output (output.c) ****/
273
/* Write program contents to a file. */
274
RSStatus rs_write_program_file(const RSProgram* prgm, FILE* f,
275
int month, int day, int year,
276
RSOutputFlags flags);
279
/**** Hex file output (output8x.c) ****/
281
/* Write program to a .73k/.73u/.8xk/.8xu or .app file. */
282
RSStatus rs_write_ti8x_file (const RSProgram* prgm, FILE* f,
283
int month, int day, int year,
284
RSOutputFlags flags);
287
/**** Binary file output (output9x.c) ****/
289
/* Write program to a .89k/.89u/.9xk/.9xu file. */
290
RSStatus rs_write_ti9x_file (const RSProgram* prgm, FILE* f,
291
int month, int day, int year,
292
RSOutputFlags flags);
295
/**** App header/certificate utility functions (header.c) ****/
297
/* Get length of a header field. */
298
void rs_get_field_size (const unsigned char* data,
299
unsigned long* fieldstart,
300
unsigned long* fieldsize);
302
/* Set length of a header field. */
303
int rs_set_field_size (unsigned char* data,
304
unsigned long fieldsize);
306
/* Find a given header field in the data. */
307
int rs_find_app_field (unsigned int type,
308
const unsigned char* data,
309
unsigned long length,
310
unsigned long* fieldhead,
311
unsigned long* fieldstart,
312
unsigned long* fieldsize);
314
/* Get value of a numeric header field. */
315
unsigned long rs_get_numeric_field (unsigned int type,
316
const unsigned char* data,
317
unsigned long length) RS_ATTR_PURE;
320
/**** Error/message logging (error.c) ****/
322
typedef void (*RSMessageFunc) (const RSKey*, const RSProgram*,
325
/* Set program name */
326
void rs_set_progname (const char* s);
328
/* Set verbosity level */
329
void rs_set_verbose (int v);
331
/* Set error logging function */
332
void rs_set_error_func (RSMessageFunc func, void* data);
334
/* Set message logging function */
335
void rs_set_message_func (RSMessageFunc func, void* data);
342
#endif /* __RABBITSIGN_H__ */