#pragma once
#include "kirk_common.h"
#include "SHA1.h"
#include "AES.h"
#ifdef __cplusplus
extern "C" {
#endif
#define KIRK_OPERATION_SUCCESS 0
#define KIRK_NOT_ENABLED 1
#define KIRK_INVALID_MODE 2
#define KIRK_HEADER_HASH_INVALID 3
#define KIRK_DATA_HASH_INVALID 4
#define KIRK_SIG_CHECK_INVALID 5
#define KIRK_UNK_1 6
#define KIRK_UNK_2 7
#define KIRK_UNK_3 8
#define KIRK_UNK_4 9
#define KIRK_UNK_5 0xA
#define KIRK_UNK_6 0xB
#define KIRK_NOT_INITIALIZED 0xC
#define KIRK_INVALID_OPERATION 0xD
#define KIRK_INVALID_SEED_CODE 0xE
#define KIRK_INVALID_SIZE 0xF
#define KIRK_DATA_SIZE_ZERO 0x10
typedef struct
{
int mode;
int unk_4;
int unk_8;
int keyseed;
int data_size;
} KIRK_AES128CBC_HEADER;
typedef struct
{
u8 AES_key[16];
u8 CMAC_key[16];
u8 CMAC_header_hash[16];
u8 CMAC_data_hash[16];
u8 unused[32];
u32 mode;
u8 ecdsa_hash;
u8 unk3[11];
u32 data_size;
u32 data_offset;
u8 unk4[8];
u8 unk5[16];
} KIRK_CMD1_HEADER;
typedef struct
{
u8 AES_key[16];
u8 header_sig_r[20];
u8 header_sig_s[20];
u8 data_sig_r[20];
u8 data_sig_s[20];
u32 mode;
u8 ecdsa_hash;
u8 unk3[11];
u32 data_size;
u32 data_offset;
u8 unk4[8];
u8 unk5[16];
} KIRK_CMD1_ECDSA_HEADER;
typedef struct
{
u8 r[0x14];
u8 s[0x14];
} ECDSA_SIG;
typedef struct
{
u8 x[0x14];
u8 y[0x14];
} ECDSA_POINT;
typedef struct
{
u32 data_size;
} KIRK_SHA1_HEADER;
typedef struct
{
u8 private_key[0x14];
ECDSA_POINT public_key;
} KIRK_CMD12_BUFFER;
typedef struct
{
u8 multiplier[0x14];
ECDSA_POINT public_key;
} KIRK_CMD13_BUFFER;
typedef struct
{
u8 enc_private[0x20];
u8 message_hash[0x14];
} KIRK_CMD16_BUFFER;
typedef struct
{
ECDSA_POINT public_key;
u8 message_hash[0x14];
ECDSA_SIG signature;
} KIRK_CMD17_BUFFER;
#define KIRK_CMD_DECRYPT_PRIVATE 1
#define KIRK_CMD_2 2
#define KIRK_CMD_3 3
#define KIRK_CMD_ENCRYPT_IV_0 4
#define KIRK_CMD_ENCRYPT_IV_FUSE 5
#define KIRK_CMD_ENCRYPT_IV_USER 6
#define KIRK_CMD_DECRYPT_IV_0 7
#define KIRK_CMD_DECRYPT_IV_FUSE 8
#define KIRK_CMD_DECRYPT_IV_USER 9
#define KIRK_CMD_PRIV_SIGN_CHECK 10
#define KIRK_CMD_SHA1_HASH 11
#define KIRK_CMD_ECDSA_GEN_KEYS 12
#define KIRK_CMD_ECDSA_MULTIPLY_POINT 13
#define KIRK_CMD_PRNG 14
#define KIRK_CMD_15 15
#define KIRK_CMD_ECDSA_SIGN 16
#define KIRK_CMD_ECDSA_VERIFY 17
#define KIRK_MODE_CMD1 1
#define KIRK_MODE_CMD2 2
#define KIRK_MODE_CMD3 3
#define KIRK_MODE_ENCRYPT_CBC 4
#define KIRK_MODE_DECRYPT_CBC 5
#define SUBCWR_NOT_16_ALGINED 0x90A
#define SUBCWR_HEADER_HASH_INVALID 0x920
#define SUBCWR_BUFFER_TOO_SMALL 0x1000
typedef struct KirkState {
u32 g_fuse90;
u32 g_fuse94;
AES_ctx aes_kirk1;
u8 PRNG_DATA[0x14];
u8 kirk_buf[0x0814];
char is_kirk_initialized;
} KirkState;
int kirk_CMD0(KirkState *kirk, u8* outbuff, const u8* inbuff, int size, int generate_trash);
int kirk_CMD1(KirkState *kirk, u8* outbuff, u8* inbuff, int size);
int kirk_CMD4(KirkState *kirk, u8* outbuff, const u8* inbuff, int size);
int kirk_CMD7(KirkState *kirk, u8* outbuff, const u8* inbuff, int size);
int kirk_CMD10(KirkState *kirk, u8* inbuff, int insize);
int kirk_CMD11(KirkState *kirk, u8* outbuff, const u8* inbuff, int size);
int kirk_CMD12(KirkState *kirk, u8* outbuff, int outsize);
int kirk_CMD13(KirkState *kirk, u8* outbuff, int outsize,u8* inbuff, int insize);
int kirk_CMD14(KirkState *kirk, u8* outbuff, int outsize);
int kirk_CMD16(KirkState *kirk, u8* outbuff, int outsize,u8* inbuff, int insize);
int kirk_CMD17(KirkState *kirk, const u8* inbuff, int insize);
int kirk_init(KirkState *kirk);
int kirk_init2(KirkState *kirk, u8 *, u32, u32, u32);
void kirk4(u8* outbuff, const u8* inbuff, size_t size, int keyId);
void kirk7(u8* outbuff, const u8* inbuff, size_t size, int keyId);
const u8* kirk_4_7_get_key(int key_type);
int kirk_CMD1_ex(KirkState *kirk, u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header);
int kirk_sceUtilsBufferCopyWithRange(KirkState *kirk, u8* outbuff, int outsize, u8* inbuff, int insize, int cmd);
void decrypt_kirk16_private(KirkState *kirk, u8 *dA_out, u8 *dA_enc);
void encrypt_kirk16_private(KirkState *kirk, u8 *dA_out, u8 *dA_dec);
int ecdsa_set_curve(const u8* p, const u8* a, const u8* b, const u8* N, const u8* Gx, const u8* Gy);
void ecdsa_set_pub(u8 *Q);
void ecdsa_set_priv(u8 *k);
int ecdsa_verify(u8 *hash, u8 *R, u8 *S);
void ecdsa_sign(KirkState *kirk, u8 *hash, u8 *R, u8 *S);
void ec_priv_to_pub(u8 *k, u8 *Q);
void ec_pub_mult(u8 *k, u8 *Q);
void bn_copy(u8 *d, const u8 *a, u32 n);
int bn_compare(const u8 *a, const u8 *b, u32 n);
void bn_reduce(u8 *d, const u8 *N, u32 n);
void bn_add(u8 *d, const u8 *a, const u8 *b, const u8 *N, u32 n);
void bn_sub(u8 *d, const u8 *a, const u8 *b, const u8 *N, u32 n);
void bn_to_mon(u8 *d, const u8 *N, u32 n);
void bn_from_mon(u8 *d, const u8 *N, u32 n);
void bn_mon_mul(u8 *d, const u8 *a, const u8 *b, const u8 *N, u32 n);
void bn_mon_inv(u8 *d, const u8 *a, const u8 *N, u32 n);
void hex_dump(const char *str, const u8 *buf, int size);
#define round_up(x,n) (-(-(x) & -(n)))
#define array_size(x) (sizeof(x) / sizeof(*(x)))
#ifdef __cplusplus
}
#endif