No more depends on sign_np.exe :3
This commit is contained in:
parent
0a8dc4c062
commit
b98eac4789
|
@ -19,12 +19,16 @@ void bn_dump(char *str, u8 *buf, u32 size)
|
|||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void bn_zero(u8 *d, u32 n)
|
||||
static void bn_zero(u8* d, u32 n)
|
||||
{
|
||||
memset(d, 0, n);
|
||||
}
|
||||
|
||||
void bn_copy(u8* d, u8* a, u32 n)
|
||||
{
|
||||
memcpy(d, a, n);
|
||||
}
|
||||
|
||||
int bn_is_zero(u8 *d, u32 n)
|
||||
{
|
||||
int i;
|
||||
|
@ -37,16 +41,11 @@ int bn_is_zero(u8 *d, u32 n)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void bn_copy(u8 *d, u8 *a, u32 n)
|
||||
{
|
||||
memcpy(d, a, n);
|
||||
}
|
||||
|
||||
int bn_compare(u8 *a, u8 *b, u32 n)
|
||||
int bn_compare(u8* a, u8* b, u32 n)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i<n; i++) {
|
||||
for (i = 0; i < n; i++) {
|
||||
if (a[i] < b[i])
|
||||
return -1;
|
||||
if (a[i] > b[i])
|
||||
|
@ -55,8 +54,7 @@ int bn_compare(u8 *a, u8 *b, u32 n)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 bn_add_1(u8 *d, u8 *a, u8 *b, u32 n)
|
||||
static u8 bn_add_1(u8* d, u8* a, u8* b, u32 n)
|
||||
{
|
||||
u32 i;
|
||||
u32 dig;
|
||||
|
@ -72,7 +70,7 @@ static u8 bn_add_1(u8 *d, u8 *a, u8 *b, u32 n)
|
|||
return c;
|
||||
}
|
||||
|
||||
static u8 bn_sub_1(u8 *d, u8 *a, u8 *b, u32 n)
|
||||
static u8 bn_sub_1(u8* d, u8* a, u8* b, u32 n)
|
||||
{
|
||||
u32 i;
|
||||
u32 dig;
|
||||
|
@ -88,13 +86,13 @@ static u8 bn_sub_1(u8 *d, u8 *a, u8 *b, u32 n)
|
|||
return 1 - c;
|
||||
}
|
||||
|
||||
void bn_reduce(u8 *d, u8 *N, u32 n)
|
||||
void bn_reduce(u8* d, u8* N, u32 n)
|
||||
{
|
||||
if (bn_compare(d, N, n) >= 0)
|
||||
bn_sub_1(d, d, N, n);
|
||||
}
|
||||
|
||||
void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
|
||||
void bn_add(u8* d, u8* a, u8* b, u8* N, u32 n)
|
||||
{
|
||||
if (bn_add_1(d, a, b, n))
|
||||
bn_sub_1(d, d, N, n);
|
||||
|
@ -102,12 +100,11 @@ void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
|
|||
bn_reduce(d, N, n);
|
||||
}
|
||||
|
||||
void bn_sub(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
|
||||
void bn_sub(u8* d, u8* a, u8* b, u8* N, u32 n)
|
||||
{
|
||||
if (bn_sub_1(d, a, b, n))
|
||||
bn_add_1(d, d, N, n);
|
||||
}
|
||||
|
||||
static const u8 inv256[0x80] = {
|
||||
0x01, 0xab, 0xcd, 0xb7, 0x39, 0xa3, 0xc5, 0xef,
|
||||
0xf1, 0x1b, 0x3d, 0xa7, 0x29, 0x13, 0x35, 0xdf,
|
||||
|
@ -127,19 +124,19 @@ static const u8 inv256[0x80] = {
|
|||
0x11, 0x3b, 0x5d, 0xc7, 0x49, 0x33, 0x55, 0xff,
|
||||
};
|
||||
|
||||
static void bn_mon_muladd_dig(u8 *d, u8 *a, u8 b, u8 *N, u32 n)
|
||||
static void bn_mon_muladd_dig(u8* d, u8* a, u8 b, u8* N, u32 n)
|
||||
{
|
||||
u32 dig;
|
||||
u32 i;
|
||||
|
||||
u8 z = -(d[n-1] + a[n-1]*b) * inv256[N[n-1]/2];
|
||||
u8 z = -(d[n - 1] + a[n - 1] * b) * inv256[N[n - 1] / 2];
|
||||
|
||||
dig = d[n-1] + a[n-1]*b + N[n-1]*z;
|
||||
dig = d[n - 1] + a[n - 1] * b + N[n - 1] * z;
|
||||
dig >>= 8;
|
||||
|
||||
for (i = n - 2; i < n; i--) {
|
||||
dig += d[i] + a[i]*b + N[i]*z;
|
||||
d[i+1] = dig;
|
||||
dig += d[i] + a[i] * b + N[i] * z;
|
||||
d[i + 1] = dig;
|
||||
dig >>= 8;
|
||||
}
|
||||
|
||||
|
@ -152,7 +149,7 @@ static void bn_mon_muladd_dig(u8 *d, u8 *a, u8 b, u8 *N, u32 n)
|
|||
bn_reduce(d, N, n);
|
||||
}
|
||||
|
||||
void bn_mon_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
|
||||
void bn_mon_mul(u8* d, u8* a, u8* b, u8* N, u32 n)
|
||||
{
|
||||
u8 t[512];
|
||||
u32 i;
|
||||
|
@ -165,31 +162,31 @@ void bn_mon_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
|
|||
bn_copy(d, t, n);
|
||||
}
|
||||
|
||||
void bn_to_mon(u8 *d, u8 *N, u32 n)
|
||||
void bn_to_mon(u8* d, u8* N, u32 n)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < 8*n; i++)
|
||||
for (i = 0; i < 8 * n; i++)
|
||||
bn_add(d, d, d, N, n);
|
||||
}
|
||||
|
||||
void bn_from_mon(u8 *d, u8 *N, u32 n)
|
||||
void bn_from_mon(u8* d, u8* N, u32 n)
|
||||
{
|
||||
u8 t[512];
|
||||
|
||||
bn_zero(t, n);
|
||||
t[n-1] = 1;
|
||||
t[n - 1] = 1;
|
||||
bn_mon_mul(d, d, t, N, n);
|
||||
}
|
||||
|
||||
static void bn_mon_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en)
|
||||
static void bn_mon_exp(u8* d, u8* a, u8* N, u32 n, u8* e, u32 en)
|
||||
{
|
||||
u8 t[512];
|
||||
u32 i;
|
||||
u8 mask;
|
||||
|
||||
bn_zero(d, n);
|
||||
d[n-1] = 1;
|
||||
d[n - 1] = 1;
|
||||
bn_to_mon(d, N, n);
|
||||
|
||||
for (i = 0; i < en; i++)
|
||||
|
@ -202,12 +199,12 @@ static void bn_mon_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en)
|
|||
}
|
||||
}
|
||||
|
||||
void bn_mon_inv(u8 *d, u8 *a, u8 *N, u32 n)
|
||||
void bn_mon_inv(u8* d, u8* a, u8* N, u32 n)
|
||||
{
|
||||
u8 t[512], s[512];
|
||||
|
||||
bn_zero(s, n);
|
||||
s[n-1] = 2;
|
||||
s[n - 1] = 2;
|
||||
bn_sub_1(t, N, s, n);
|
||||
bn_mon_exp(d, a, N, n, t, n);
|
||||
}
|
||||
|
|
430
CHOVY-KIRK/ec.c
430
CHOVY-KIRK/ec.c
|
@ -4,35 +4,33 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kirk_engine.h"
|
||||
#include "ecdsa.h"
|
||||
|
||||
struct point {
|
||||
u8 x[20];
|
||||
u8 y[20];
|
||||
};
|
||||
|
||||
static u8 ec_p[20];
|
||||
static u8 ec_a[20]; // mon
|
||||
static u8 ec_b[20]; // mon
|
||||
static u8 ec_N[20];
|
||||
static struct point ec_G; // mon
|
||||
static struct point ec_Q; // mon
|
||||
static u8 ec_k[20]; // private key
|
||||
u8 ec_p[20];
|
||||
u8 ec_a[20];
|
||||
u8 ec_b[20];
|
||||
u8 ec_N[21];
|
||||
struct point ec_G; // mon
|
||||
struct point ec_Q; // mon
|
||||
u8 ec_k[21];
|
||||
|
||||
static void elt_copy(u8 *d, u8 *a)
|
||||
static void elt_copy(u8* d, u8* a)
|
||||
{
|
||||
memcpy(d, a, 20);
|
||||
}
|
||||
|
||||
static void elt_zero(u8 *d)
|
||||
static void elt_zero(u8* d)
|
||||
{
|
||||
memset(d, 0, 20);
|
||||
}
|
||||
|
||||
static int elt_is_zero(u8 *d)
|
||||
static int elt_is_zero(u8* d)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
|
@ -43,61 +41,85 @@ static int elt_is_zero(u8 *d)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void elt_add(u8 *d, u8 *a, u8 *b)
|
||||
static void elt_add(u8* d, u8* a, u8* b)
|
||||
{
|
||||
bn_add(d, a, b, ec_p, 20);
|
||||
}
|
||||
|
||||
static void elt_sub(u8 *d, u8 *a, u8 *b)
|
||||
static void elt_sub(u8* d, u8* a, u8* b)
|
||||
{
|
||||
bn_sub(d, a, b, ec_p, 20);
|
||||
}
|
||||
|
||||
static void elt_mul(u8 *d, u8 *a, u8 *b)
|
||||
static void elt_mul(u8* d, u8* a, u8* b)
|
||||
{
|
||||
bn_mon_mul(d, a, b, ec_p, 20);
|
||||
}
|
||||
|
||||
static void elt_square(u8 *d, u8 *a)
|
||||
static void elt_square(u8* d, u8* a)
|
||||
{
|
||||
elt_mul(d, a, a);
|
||||
}
|
||||
|
||||
static void elt_inv(u8 *d, u8 *a)
|
||||
static void elt_inv(u8* d, u8* a)
|
||||
{
|
||||
u8 s[20];
|
||||
elt_copy(s, a);
|
||||
bn_mon_inv(d, s, ec_p, 20);
|
||||
}
|
||||
|
||||
static void point_to_mon(struct point *p)
|
||||
static void point_to_mon(struct point* p)
|
||||
{
|
||||
bn_to_mon(p->x, ec_p, 20);
|
||||
bn_to_mon(p->y, ec_p, 20);
|
||||
}
|
||||
|
||||
static void point_from_mon(struct point *p)
|
||||
static void point_from_mon(struct point* p)
|
||||
{
|
||||
bn_from_mon(p->x, ec_p, 20);
|
||||
bn_from_mon(p->y, ec_p, 20);
|
||||
}
|
||||
|
||||
static void point_zero(struct point *p)
|
||||
#if 0
|
||||
static int point_is_on_curve(u8* p)
|
||||
{
|
||||
u8 s[20], t[20];
|
||||
u8* x, * y;
|
||||
|
||||
x = p;
|
||||
y = p + 20;
|
||||
|
||||
elt_square(t, x);
|
||||
elt_mul(s, t, x);
|
||||
|
||||
elt_mul(t, x, ec_a);
|
||||
elt_add(s, s, t);
|
||||
|
||||
elt_add(s, s, ec_b);
|
||||
|
||||
elt_square(t, y);
|
||||
elt_sub(s, s, t);
|
||||
|
||||
return elt_is_zero(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void point_zero(struct point* p)
|
||||
{
|
||||
elt_zero(p->x);
|
||||
elt_zero(p->y);
|
||||
}
|
||||
|
||||
static int point_is_zero(struct point *p)
|
||||
static int point_is_zero(struct point* p)
|
||||
{
|
||||
return elt_is_zero(p->x) && elt_is_zero(p->y);
|
||||
}
|
||||
|
||||
static void point_double(struct point *r, struct point *p)
|
||||
static void point_double(struct point* r, struct point* p)
|
||||
{
|
||||
u8 s[20], t[20];
|
||||
struct point pp;
|
||||
u8 *px, *py, *rx, *ry;
|
||||
u8* px, * py, * rx, * ry;
|
||||
|
||||
pp = *p;
|
||||
|
||||
|
@ -111,27 +133,27 @@ static void point_double(struct point *r, struct point *p)
|
|||
return;
|
||||
}
|
||||
|
||||
elt_square(t, px); // t = px*px
|
||||
elt_add(s, t, t); // s = 2*px*px
|
||||
elt_add(s, s, t); // s = 3*px*px
|
||||
elt_add(s, s, ec_a);// s = 3*px*px + a
|
||||
elt_add(t, py, py); // t = 2*py
|
||||
elt_inv(t, t); // t = 1/(2*py)
|
||||
elt_mul(s, s, t); // s = (3*px*px+a)/(2*py)
|
||||
elt_square(t, px); // t = px*px
|
||||
elt_add(s, t, t); // s = 2*px*px
|
||||
elt_add(s, s, t); // s = 3*px*px
|
||||
elt_add(s, s, ec_a); // s = 3*px*px + a
|
||||
elt_add(t, py, py); // t = 2*py
|
||||
elt_inv(t, t); // t = 1/(2*py)
|
||||
elt_mul(s, s, t); // s = (3*px*px+a)/(2*py)
|
||||
|
||||
elt_square(rx, s); // rx = s*s
|
||||
elt_add(t, px, px); // t = 2*px
|
||||
elt_sub(rx, rx, t); // rx = s*s - 2*px
|
||||
elt_square(rx, s); // rx = s*s
|
||||
elt_add(t, px, px); // t = 2*px
|
||||
elt_sub(rx, rx, t); // rx = s*s - 2*px
|
||||
|
||||
elt_sub(t, px, rx); // t = -(rx-px)
|
||||
elt_mul(ry, s, t); // ry = -s*(rx-px)
|
||||
elt_sub(ry, ry, py);// ry = -s*(rx-px) - py
|
||||
elt_sub(t, px, rx); // t = -(rx-px)
|
||||
elt_mul(ry, s, t); // ry = -s*(rx-px)
|
||||
elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
|
||||
}
|
||||
|
||||
static void point_add(struct point *r, struct point *p, struct point *q)
|
||||
static void point_add(struct point* r, struct point* p, struct point* q)
|
||||
{
|
||||
u8 s[20], t[20], u[20];
|
||||
u8 *px, *py, *qx, *qy, *rx, *ry;
|
||||
u8* px, * py, * qx, * qy, * rx, * ry;
|
||||
struct point pp, qq;
|
||||
|
||||
pp = *p;
|
||||
|
@ -168,27 +190,27 @@ static void point_add(struct point *r, struct point *p, struct point *q)
|
|||
return;
|
||||
}
|
||||
|
||||
elt_inv(t, u); // t = 1/(qx-px)
|
||||
elt_sub(u, qy, py); // u = qy-py
|
||||
elt_mul(s, t, u); // s = (qy-py)/(qx-px)
|
||||
elt_inv(t, u); // t = 1/(qx-px)
|
||||
elt_sub(u, qy, py); // u = qy-py
|
||||
elt_mul(s, t, u); // s = (qy-py)/(qx-px)
|
||||
|
||||
elt_square(rx, s); // rx = s*s
|
||||
elt_add(t, px, qx); // t = px+qx
|
||||
elt_sub(rx, rx, t); // rx = s*s - (px+qx)
|
||||
elt_square(rx, s); // rx = s*s
|
||||
elt_add(t, px, qx); // t = px+qx
|
||||
elt_sub(rx, rx, t); // rx = s*s - (px+qx)
|
||||
|
||||
elt_sub(t, px, rx); // t = -(rx-px)
|
||||
elt_mul(ry, s, t); // ry = -s*(rx-px)
|
||||
elt_sub(ry, ry, py);// ry = -s*(rx-px) - py
|
||||
elt_sub(t, px, rx); // t = -(rx-px)
|
||||
elt_mul(ry, s, t); // ry = -s*(rx-px)
|
||||
elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
|
||||
}
|
||||
|
||||
static void point_mul(struct point *d, u8 *a, struct point *b)
|
||||
static void point_mul(struct point* d, u8* a, struct point* b)
|
||||
{
|
||||
u32 i;
|
||||
u8 mask;
|
||||
|
||||
point_zero(d);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < 21; i++)
|
||||
for (mask = 0x80; mask != 0; mask >>= 1) {
|
||||
point_double(d, d);
|
||||
if ((a[i] & mask) != 0)
|
||||
|
@ -196,7 +218,7 @@ static void point_mul(struct point *d, u8 *a, struct point *b)
|
|||
}
|
||||
}
|
||||
|
||||
static void generate_ecdsa_norandom(u8* outR, u8* outS, u8* k, u8* hash)
|
||||
static void generate_ecdsa(u8* outR, u8* outS, u8* k, u8* hash)
|
||||
{
|
||||
u8 e[21];
|
||||
u8 kk[21];
|
||||
|
@ -236,155 +258,66 @@ static void generate_ecdsa_norandom(u8* outR, u8* outS, u8* k, u8* hash)
|
|||
memcpy(outS, S + 1, 0x20);
|
||||
}
|
||||
|
||||
static void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash, u8 *random)
|
||||
static int check_ecdsa(struct point* Q, u8* inR, u8* inS, u8* hash)
|
||||
{
|
||||
u8 e[20];
|
||||
u8 kk[20];
|
||||
u8 m[20];
|
||||
u8 minv[20];
|
||||
struct point mG;
|
||||
u8 Sinv[21];
|
||||
u8 e[21], R[21], S[21];
|
||||
u8 w1[21], w2[21];
|
||||
struct point r1, r2;
|
||||
u8 rr[21];
|
||||
|
||||
memcpy(e, hash, 20);
|
||||
bn_reduce(e, ec_N, 20);
|
||||
e[0] = 0;
|
||||
memcpy(e + 1, hash, 20);
|
||||
bn_reduce(e, ec_N, 21);
|
||||
R[0] = 0;
|
||||
memcpy(R + 1, inR, 20);
|
||||
bn_reduce(R, ec_N, 21);
|
||||
S[0] = 0;
|
||||
memcpy(S + 1, inS, 20);
|
||||
bn_reduce(S, ec_N, 21);
|
||||
|
||||
if(random==NULL){
|
||||
do{
|
||||
kirk_CMD14(m, 20);
|
||||
}while(bn_compare(m, ec_N, 20) >= 0);
|
||||
}else{
|
||||
memcpy(m, random, 20);
|
||||
}
|
||||
bn_to_mon(R, ec_N, 21);
|
||||
bn_to_mon(S, ec_N, 21);
|
||||
bn_to_mon(e, ec_N, 21);
|
||||
// make Sinv = 1/S
|
||||
bn_mon_inv(Sinv, S, ec_N, 21);
|
||||
// w1 = m * Sinv
|
||||
bn_mon_mul(w1, e, Sinv, ec_N, 21);
|
||||
// w2 = r * Sinv
|
||||
bn_mon_mul(w2, R, Sinv, ec_N, 21);
|
||||
|
||||
point_mul(&mG, m, &ec_G);
|
||||
point_from_mon(&mG);
|
||||
elt_copy(R, mG.x);
|
||||
// mod N both
|
||||
bn_from_mon(w1, ec_N, 21);
|
||||
bn_from_mon(w2, ec_N, 21);
|
||||
|
||||
bn_copy(kk, k, 20);
|
||||
bn_reduce(kk, ec_N, 20);
|
||||
bn_to_mon(m, ec_N, 20);
|
||||
bn_to_mon(e, ec_N, 20);
|
||||
bn_to_mon(R, ec_N, 20);
|
||||
bn_to_mon(kk, ec_N, 20);
|
||||
|
||||
bn_mon_mul(S, R, kk, ec_N, 20);
|
||||
bn_add(kk, S, e, ec_N, 20);
|
||||
bn_mon_inv(minv, m, ec_N, 20);
|
||||
bn_mon_mul(S, minv, kk, ec_N, 20);
|
||||
|
||||
bn_from_mon(R, ec_N, 20);
|
||||
bn_from_mon(S, ec_N, 20);
|
||||
}
|
||||
|
||||
static int check_ecdsa(struct point *Q, u8 *R, u8 *S, u8 *hash)
|
||||
{
|
||||
u8 Sinv[20];
|
||||
u8 e[20];
|
||||
u8 w1[20], w2[20];
|
||||
struct point r1, r2, r3;
|
||||
u8 rr[20];
|
||||
|
||||
memcpy(e, hash, 20);
|
||||
bn_reduce(e, ec_N, 20);
|
||||
|
||||
// Sinv = INV(s)
|
||||
bn_to_mon(S, ec_N, 20);
|
||||
bn_mon_inv(Sinv, S, ec_N, 20);
|
||||
|
||||
// w1 = e*Sinv
|
||||
bn_to_mon(e, ec_N, 20);
|
||||
bn_mon_mul(w1, e, Sinv, ec_N, 20);
|
||||
bn_from_mon(w1, ec_N, 20);
|
||||
|
||||
// w2 = R*Sinv
|
||||
bn_to_mon(R, ec_N, 20);
|
||||
bn_mon_mul(w2, R, Sinv, ec_N, 20);
|
||||
bn_from_mon(w2, ec_N, 20);
|
||||
|
||||
// r1 = w1*G
|
||||
// r1 = m/s * G
|
||||
point_mul(&r1, w1, &ec_G);
|
||||
// r2 = w2*Q
|
||||
// r2 = r/s * P
|
||||
point_mul(&r2, w2, Q);
|
||||
// r3 = r1+r2
|
||||
point_add(&r3, &r1, &r2);
|
||||
|
||||
point_from_mon(&r3);
|
||||
memcpy(rr, r3.x, 20);
|
||||
bn_reduce(rr, ec_N, 20);
|
||||
//r1 = r1 + r2
|
||||
point_add(&r1, &r1, &r2);
|
||||
|
||||
bn_from_mon(R, ec_N, 20);
|
||||
bn_from_mon(S, ec_N, 20);
|
||||
point_from_mon(&r1);
|
||||
|
||||
return bn_compare(rr, R, 20);
|
||||
rr[0] = 0;
|
||||
memcpy(rr + 1, r1.x, 20);
|
||||
bn_reduce(rr, ec_N, 21);
|
||||
|
||||
bn_from_mon(R, ec_N, 21);
|
||||
bn_from_mon(S, ec_N, 21);
|
||||
|
||||
return (bn_compare(rr, R, 21) == 0);
|
||||
}
|
||||
|
||||
void ecdsa_sign_fixed(u8 *hash, u8 *fixed_m, u8 *fixed_r, u8 *S)
|
||||
void ec_priv_to_pub(u8* k, u8* Q)
|
||||
{
|
||||
u8 minv[20], m[20], k[20], r[20], z[20];
|
||||
|
||||
memcpy(z, hash, 20);
|
||||
memcpy(k, ec_k, 20);
|
||||
memcpy(m, fixed_m, 20);
|
||||
memcpy(r, fixed_r, 20);
|
||||
|
||||
bn_to_mon(m, ec_N, 20);
|
||||
bn_mon_inv(minv, m, ec_N, 20);
|
||||
|
||||
bn_to_mon(k, ec_N, 20);
|
||||
bn_to_mon(r, ec_N, 20);
|
||||
bn_mon_mul(z, k, r, ec_N, 20);
|
||||
bn_from_mon(z, ec_N, 20);
|
||||
|
||||
bn_add(z, z, hash, ec_N, 20);
|
||||
|
||||
bn_to_mon(z, ec_N, 20);
|
||||
bn_mon_mul(S, minv, z, ec_N, 20);
|
||||
bn_from_mon(S, ec_N, 20);
|
||||
}
|
||||
|
||||
void ecdsa_set_curve(ECDSA_PARAM *param)
|
||||
{
|
||||
memcpy(ec_p, param->p, 20);
|
||||
memcpy(ec_a, param->a, 20);
|
||||
memcpy(ec_b, param->b, 20);
|
||||
memcpy(ec_N, param->N, 20);
|
||||
memcpy(ec_G.x, param->Gx, 20);
|
||||
memcpy(ec_G.y, param->Gy, 20);
|
||||
|
||||
bn_to_mon(ec_a, ec_p, 20);
|
||||
bn_to_mon(ec_b, ec_p, 20);
|
||||
|
||||
point_to_mon(&ec_G);
|
||||
}
|
||||
|
||||
void ecdsa_set_N(u8 *N)
|
||||
{
|
||||
memcpy(ec_N, N, 20);
|
||||
}
|
||||
|
||||
void ecdsa_set_pub(u8 *Qx, u8 *Qy)
|
||||
{
|
||||
memcpy(ec_Q.x, Qx, 20);
|
||||
memcpy(ec_Q.y, Qy, 20);
|
||||
point_to_mon(&ec_Q);
|
||||
}
|
||||
|
||||
void ecdsa_set_priv(u8 *k)
|
||||
{
|
||||
memcpy(ec_k, k, sizeof ec_k);
|
||||
}
|
||||
|
||||
int ecdsa_verify(u8 *hash, u8 *R, u8 *S)
|
||||
{
|
||||
return check_ecdsa(&ec_Q, R, S, hash);
|
||||
}
|
||||
void ecdsa_sign_norandom(u8* hash, u8* R, u8* S)
|
||||
{
|
||||
generate_ecdsa_norandom(R, S, ec_k, hash);
|
||||
}
|
||||
|
||||
void ecdsa_sign(u8 *hash, u8 *R, u8 *S, u8 *random)
|
||||
{
|
||||
generate_ecdsa(R, S, ec_k, hash, random);
|
||||
struct point ec_temp;
|
||||
bn_to_mon(k, ec_N, 21);
|
||||
point_mul(&ec_temp, k, &ec_G);
|
||||
point_from_mon(&ec_temp);
|
||||
memcpy(Q, ec_temp.x, 20);
|
||||
memcpy(Q + 20, ec_temp.y, 20);
|
||||
}
|
||||
|
||||
void ec_pub_mult(u8* k, u8* Q)
|
||||
|
@ -396,64 +329,79 @@ void ec_pub_mult(u8* k, u8* Q)
|
|||
memcpy(Q + 20, ec_temp.y, 20);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
// calculate the random and private key from signs with same r value
|
||||
void ecdsa_find_m_k(u8 *sig_r, u8 *sig_s1, u8 *hash1, u8 *sig_s2, u8 *hash2, u8 *N, u8 *ret_m, u8 *ret_k)
|
||||
int ecdsa_set_curve(u8* p, u8* a, u8* b, u8* N, u8* Gx, u8* Gy)
|
||||
{
|
||||
u8 e1[20], e2[20];
|
||||
u8 s1[20], s2[20];
|
||||
u8 sinv[20], m[20];
|
||||
u8 r[20], rinv[20], kk[20];
|
||||
memcpy(ec_p, p, 20);
|
||||
memcpy(ec_a, a, 20);
|
||||
memcpy(ec_b, b, 20);
|
||||
memcpy(ec_N, N, 21);
|
||||
|
||||
// e1
|
||||
memcpy(e1, hash1, 20);
|
||||
// e2
|
||||
memcpy(e2, hash2, 20);
|
||||
// s1, s2
|
||||
memcpy(s1, sig_s1, 20);
|
||||
memcpy(s2, sig_s2, 20);
|
||||
bn_to_mon(ec_a, ec_p, 20);
|
||||
bn_to_mon(ec_b, ec_p, 20);
|
||||
|
||||
// restore random m
|
||||
// s1 = s1-s2
|
||||
bn_sub(s1, s1, s2, N, 20);
|
||||
// e1 = e1-e2
|
||||
bn_sub(e1, e1, e2, N, 20);
|
||||
|
||||
bn_to_mon(s1, N, 20);
|
||||
bn_to_mon(e1, N, 20);
|
||||
|
||||
// m = (e1-e2)/(s1-s2)
|
||||
bn_mon_inv(sinv, s1, N, 20);
|
||||
bn_mon_mul(m, sinv, e1, N, 20);
|
||||
bn_from_mon(m, N, 20);
|
||||
|
||||
bn_dump("random m", m, 20);
|
||||
memcpy(ret_m, m, 20);
|
||||
|
||||
// restore private key
|
||||
memcpy(e1, hash1, 20);
|
||||
memcpy(s1, sig_s1, 20);
|
||||
memcpy(r, sig_r, 20);
|
||||
|
||||
// kk = m*s
|
||||
bn_to_mon(s1, N, 20);
|
||||
bn_to_mon(m, N, 20);
|
||||
bn_mon_mul(kk, m, s1, N, 20);
|
||||
|
||||
// kk = m*s-e
|
||||
bn_from_mon(kk, N, 20);
|
||||
bn_sub(kk, kk, e1, N, 20);
|
||||
bn_to_mon(kk, N, 20);
|
||||
|
||||
// kk = (m*s-e)/r
|
||||
bn_to_mon(r, N, 20);
|
||||
bn_mon_inv(rinv, r, N, 20);
|
||||
bn_mon_mul(kk, rinv, kk, N, 20);
|
||||
bn_from_mon(kk, N, 20);
|
||||
|
||||
bn_dump("private key", kk, 20);
|
||||
memcpy(ret_k, kk, 20);
|
||||
memcpy(ec_G.x, Gx, 20);
|
||||
memcpy(ec_G.y, Gy, 20);
|
||||
point_to_mon(&ec_G);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ecdsa_set_pub(u8* Q)
|
||||
{
|
||||
memcpy(ec_Q.x, Q, 20);
|
||||
memcpy(ec_Q.y, Q + 20, 20);
|
||||
point_to_mon(&ec_Q);
|
||||
}
|
||||
|
||||
void ecdsa_set_priv(u8* ink)
|
||||
{
|
||||
u8 k[21];
|
||||
k[0] = 0;
|
||||
memcpy(k + 1, ink, 20);
|
||||
bn_reduce(k, ec_N, 21);
|
||||
|
||||
memcpy(ec_k, k, sizeof ec_k);
|
||||
}
|
||||
|
||||
int ecdsa_verify(u8* hash, u8* R, u8* S)
|
||||
{
|
||||
return check_ecdsa(&ec_Q, R, S, hash);
|
||||
}
|
||||
|
||||
void ecdsa_sign(u8* hash, u8* R, u8* S)
|
||||
{
|
||||
generate_ecdsa(R, S, ec_k, hash);
|
||||
}
|
||||
|
||||
int point_is_on_curve(u8* p)
|
||||
{
|
||||
u8 s[20], t[20];
|
||||
u8* x, * y;
|
||||
|
||||
x = p;
|
||||
y = p + 20;
|
||||
|
||||
elt_square(t, x);
|
||||
elt_mul(s, t, x);// s = x^3
|
||||
|
||||
elt_mul(t, x, ec_a);
|
||||
elt_add(s, s, t); //s = x^3 + a *x
|
||||
|
||||
elt_add(s, s, ec_b);//s = x^3 + a *x + b
|
||||
|
||||
elt_square(t, y); //t = y^2
|
||||
elt_sub(s, s, t); // is s - t = 0?
|
||||
hex_dump("S", s, 20);
|
||||
hex_dump("T", t, 20);
|
||||
return elt_is_zero(s);
|
||||
}
|
||||
|
||||
void dump_ecc(void)
|
||||
{
|
||||
hex_dump("P", ec_p, 20);
|
||||
hex_dump("a", ec_a, 20);
|
||||
hex_dump("b", ec_b, 20);
|
||||
hex_dump("N", ec_N, 21);
|
||||
hex_dump("Gx", ec_G.x, 20);
|
||||
hex_dump("Gy", ec_G.y, 20);
|
||||
}
|
|
@ -6,24 +6,11 @@
|
|||
#ifndef ECDSA_H__
|
||||
#define ECDSA_H__ 1
|
||||
|
||||
typedef struct {
|
||||
u8 p[20];
|
||||
u8 a[20];
|
||||
u8 b[20];
|
||||
u8 N[20];
|
||||
u8 Gx[20];
|
||||
u8 Gy[20];
|
||||
}ECDSA_PARAM;
|
||||
|
||||
void ecdsa_set_curve(ECDSA_PARAM *param);
|
||||
void ecdsa_set_N(u8 *N);
|
||||
void ecdsa_set_pub(u8 *Qx, u8 *Qy);
|
||||
int ecdsa_set_curve(u8* p, u8* a, u8* b, u8* N, u8* Gx, u8* Gy);
|
||||
void ecdsa_set_pub(u8 *Qx);
|
||||
void ecdsa_set_priv(u8 *k);
|
||||
int ecdsa_verify(u8 *hash, u8 *R, u8 *S);
|
||||
void ecdsa_sign(u8 *hash, u8 *R, u8 *S, u8 *random);
|
||||
void ecdsa_sign_norandom(u8* hash, u8* R, u8* S);
|
||||
void ecdsa_sign_fixed(u8 *hash, u8 *fixed_m, u8 *fixed_r, u8 *S);
|
||||
void ecdsa_find_m_k(u8 *sig_r, u8 *sig_s1, u8 *hash1, u8 *sig_s2, u8 *hash2, u8 *N, u8 *ret_m, u8 *ret_k);
|
||||
void ecdsa_sign(u8* hash, u8* R, u8* S);
|
||||
|
||||
void bn_dump(char *msg, u8 *d, u32 n);
|
||||
int bn_is_zero(u8 *d, u32 n);
|
||||
|
|
|
@ -14,9 +14,7 @@ unsigned __int8 pubkey_edat_x[20] = {0x1F,0x07,0x2B,0xCC,0xC1,0x62,0xF2,0xCF,0xA
|
|||
unsigned __int8 pubkey_edat_y[20] = {0x53,0x01,0xF4,0xE3,0x70,0xC3,0xED,0xE2,0xD4,0xF5,0xDB,0xC3,0xA7,0xDE,0x8C,0xAA,0xE8,0xAD,0x5B,0x7D};
|
||||
|
||||
|
||||
unsigned __int8 edat_aeskey[16] = {0xBA,0x87,0xE4,0xAB,0x2C,0x60,0x5F,0x59,0xB8,0x3B,0xDB,0xA6,0x82,0xFD,0xAE,0x14};
|
||||
|
||||
extern ECDSA_PARAM ecdsa_app;
|
||||
unsigned __int8 edat_aeskey[16] = { 0xBA,0x87,0xE4,0xAB,0x2C,0x60,0x5F,0x59,0xB8,0x3B,0xDB,0xA6,0x82,0xFD,0xAE,0x14 };
|
||||
extern unsigned __int8 priv_key_edata[];
|
||||
|
||||
int verbose = 0;
|
||||
|
@ -30,7 +28,7 @@ int edata_check_ecdsa(unsigned __int8 *edata_buf)
|
|||
|
||||
printf("EDATA ID: %s\n", (char*)(edata_buf+0x10));
|
||||
|
||||
ecdsa_set_curve(&ecdsa_app);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b2, ec_N2, Gx2, Gy2);
|
||||
ecdsa_set_pub(pubkey_edat_x, pubkey_edat_y);
|
||||
|
||||
SHA1(edata_buf, 0x58, sha1_hash);
|
||||
|
@ -68,7 +66,7 @@ int edata_sign_free(unsigned __int8 *edata_buf, unsigned __int8 *pgd_key)
|
|||
*(unsigned __int32*)(edata_buf+8) = 0x01000000;
|
||||
|
||||
// build ecdsa
|
||||
ecdsa_set_curve(&ecdsa_app);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b2, ec_N2, Gx2, Gy2);
|
||||
ecdsa_set_priv(priv_key_edata);
|
||||
SHA1(edata_buf, 0x58, sha1_hash);
|
||||
ecdsa_sign(sha1_hash, edata_buf+0x58, edata_buf+0x6c, NULL);
|
||||
|
|
|
@ -14,15 +14,6 @@
|
|||
|
||||
|
||||
|
||||
// ECDSA param of kirk1
|
||||
ECDSA_PARAM ecdsa_kirk1 = {
|
||||
.p = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
|
||||
.a = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC},
|
||||
.b = {0x65,0xD1,0x48,0x8C,0x03,0x59,0xE2,0x34,0xAD,0xC9,0x5B,0xD3,0x90,0x80,0x14,0xBD,0x91,0xA5,0x25,0xF9},
|
||||
.N = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xb5,0xc6,0x17,0xf2,0x90,0xea,0xe1,0xdb,0xad,0x8f},
|
||||
.Gx = {0x22,0x59,0xAC,0xEE,0x15,0x48,0x9C,0xB0,0x96,0xA8,0x82,0xF0,0xAE,0x1C,0xF9,0xFD,0x8E,0xE5,0xF8,0xFA},
|
||||
.Gy = {0x60,0x43,0x58,0x45,0x6D,0x0A,0x1C,0xB2,0x90,0x8D,0xE9,0x0F,0x27,0xD7,0x5C,0x82,0xBE,0xC1,0x08,0xC0},
|
||||
};
|
||||
|
||||
// ECDSA private key of kirk1
|
||||
u8 priv_key_kirk1[20] = {0xF3,0x92,0xE2,0x64,0x90,0xB8,0x0F,0xD8,0x89,0xF2,0xD9,0x72,0x2C,0x1F,0x34,0xD7,0x27,0x4F,0x98,0x3D};
|
||||
|
@ -39,14 +30,6 @@ u8 kirk1_ec_m_data[20] = {0x15,0xee,0x16,0x24,0x12,0x09,0x58,0x16,0x0f,0x8b,0x1a
|
|||
u8 kirk1_ec_r_data[20] = {0xcd,0xe3,0x88,0xa6,0x3c,0x1d,0x57,0xdc,0x5e,0x94,0xee,0xac,0x2e,0x6c,0x9f,0x2e,0x81,0xc7,0x1c,0x58};
|
||||
|
||||
// ECDSA param of applations
|
||||
ECDSA_PARAM ecdsa_app = {
|
||||
.p = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
|
||||
.a = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC},
|
||||
.b = {0xA6,0x8B,0xED,0xC3,0x34,0x18,0x02,0x9C,0x1D,0x3C,0xE3,0x3B,0x9A,0x32,0x1F,0xCC,0xBB,0x9E,0x0F,0x0B},
|
||||
.N = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xB5,0xAE,0x3C,0x52,0x3E,0x63,0x94,0x4F,0x21,0x27},
|
||||
.Gx = {0x12,0x8E,0xC4,0x25,0x64,0x87,0xFD,0x8F,0xDF,0x64,0xE2,0x43,0x7B,0xC0,0xA1,0xF6,0xD5,0xAF,0xDE,0x2C},
|
||||
.Gy = {0x59,0x58,0x55,0x7E,0xB1,0xDB,0x00,0x12,0x60,0x42,0x55,0x24,0xDB,0xC3,0x79,0xD5,0xAC,0x5F,0x4A,0xDF},
|
||||
};
|
||||
|
||||
// ECDSA private key of EDATA
|
||||
u8 priv_key_edata[20] = {0xe5,0xc4,0xd0,0xa8,0x24,0x9a,0x6f,0x27,0xe5,0xe0,0xc9,0xd5,0x34,0xf4,0xda,0x15,0x22,0x3f,0x42,0xad};
|
||||
|
@ -377,18 +360,18 @@ int kirk_CMD0(void* outbuff, void* inbuff, int size)
|
|||
u8 *sign_s, *sign_r;
|
||||
u8 sign_e[20];
|
||||
|
||||
ecdsa_set_curve(&ecdsa_kirk1);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b1, ec_N1, Gx1, Gy1);
|
||||
ecdsa_set_priv(priv_key_kirk1);
|
||||
|
||||
SHA1((char*)outbuff+0x60, 0x30, sign_e);
|
||||
sign_r = (char*)outbuff+0x10;
|
||||
sign_s = (char*)outbuff+0x10+0x14;
|
||||
ecdsa_sign(sign_e, sign_r, sign_s, NULL);
|
||||
ecdsa_sign(sign_e, sign_r, sign_s);
|
||||
|
||||
SHA1((char*)outbuff+0x60, 0x30+chk_size+header->data_offset, sign_e);
|
||||
sign_r = (char*)outbuff+0x10+0x28;
|
||||
sign_s = (char*)outbuff+0x10+0x3C;
|
||||
ecdsa_sign(sign_e, sign_r, sign_s, NULL);
|
||||
ecdsa_sign(sign_e, sign_r, sign_s);
|
||||
|
||||
|
||||
//Encrypt keys
|
||||
|
@ -439,7 +422,7 @@ int kirk_CMD1(void* outbuff, void* inbuff, int size)
|
|||
u8 *sign_s, *sign_r;
|
||||
u8 sign_e[20];
|
||||
|
||||
ecdsa_set_curve(&ecdsa_kirk1);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b1, ec_N1, Gx1, Gy1);
|
||||
ecdsa_set_pub(pub_key_kirk1_x, pub_key_kirk1_y);
|
||||
|
||||
SHA1((char*)inbuff+0x60, 0x30, sign_e);
|
||||
|
@ -621,7 +604,7 @@ int kirk_CMD12(void *outbuff, int size)
|
|||
if(size!=0x3c)
|
||||
return KIRK_INVALID_SIZE;
|
||||
|
||||
ecdsa_set_curve(&ecdsa_app);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b2, ec_N2, Gx2, Gy2);
|
||||
|
||||
kirk_CMD14(priv_key, 20);
|
||||
|
||||
|
@ -644,7 +627,7 @@ int kirk_CMD13(u8* outbuff, int outsize, u8* inbuff, int insize)
|
|||
if (outsize != 0x28) return KIRK_INVALID_SIZE;
|
||||
if (insize != 0x3C) return KIRK_INVALID_SIZE;
|
||||
|
||||
ecdsa_set_curve(&ecdsa_app);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b2, ec_N2, Gx2, Gy2);
|
||||
ecdsa_set_pub((u8*)pointmult->public_key.x, (u8*)pointmult->public_key.y);
|
||||
memcpy(k + 1, pointmult->multiplier, 0x14);
|
||||
ec_pub_mult(k, outbuff);
|
||||
|
@ -653,22 +636,58 @@ int kirk_CMD13(u8* outbuff, int outsize, u8* inbuff, int insize)
|
|||
}
|
||||
|
||||
|
||||
int kirk_CMD14(void* outbuff, int size)
|
||||
int kirk_CMD14(u8* outbuff, int outsize)
|
||||
{
|
||||
int i;
|
||||
u8* buf = (u8*)outbuff;
|
||||
u8 temp[0x104];
|
||||
KIRK_SHA1_HEADER* header = (KIRK_SHA1_HEADER*)temp;
|
||||
|
||||
if(is_kirk_initialized == 0)
|
||||
kirk_init();
|
||||
// Some randomly selected data for a "key" to add to each randomization
|
||||
u8 key[0x10] = { 0xA7, 0x2E, 0x4C, 0xB6, 0xC3, 0x34, 0xDF, 0x85, 0x70, 0x01, 0x49, 0xFC, 0xC0, 0x87, 0xC4, 0x77 };
|
||||
u32 curtime;
|
||||
|
||||
for(i=0; i<size; i++){
|
||||
buf[i] = rand()%256;
|
||||
if (outsize <= 0) return KIRK_OPERATION_SUCCESS;
|
||||
|
||||
memcpy(temp + 4, PRNG_DATA, 0x14);
|
||||
|
||||
// This uses the standard C time function for portability.
|
||||
curtime = (u32)time(0);
|
||||
temp[0x18] = curtime & 0xFF;
|
||||
temp[0x19] = (curtime >> 8) & 0xFF;
|
||||
temp[0x1A] = (curtime >> 16) & 0xFF;
|
||||
temp[0x1B] = (curtime >> 24) & 0xFF;
|
||||
memcpy(&temp[0x1C], key, 0x10);
|
||||
|
||||
// This leaves the remainder of the 0x100 bytes in temp to whatever remains on the stack
|
||||
// in an uninitialized state. This should add unpredicableness to the results as well
|
||||
header->data_size = 0x100;
|
||||
kirk_CMD11(PRNG_DATA, temp, 0x104);
|
||||
|
||||
while (outsize)
|
||||
{
|
||||
int blockrem = outsize % 0x14;
|
||||
int block = outsize / 0x14;
|
||||
|
||||
if (block)
|
||||
{
|
||||
memcpy(outbuff, PRNG_DATA, 0x14);
|
||||
outbuff += 0x14;
|
||||
outsize -= 0x14;
|
||||
kirk_CMD14(outbuff, outsize);
|
||||
}
|
||||
else {
|
||||
if (blockrem)
|
||||
{
|
||||
memcpy(outbuff, PRNG_DATA, blockrem);
|
||||
outsize -= blockrem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int kirk_CMD16(u8* outbuff, int outsize, u8* inbuff, int insize)
|
||||
{
|
||||
u8 dec_private[0x20];
|
||||
|
@ -683,9 +702,9 @@ int kirk_CMD16(u8* outbuff, int outsize, u8* inbuff, int insize)
|
|||
// Clear out the padding for safety
|
||||
memset(&dec_private[0x14], 0, 0xC);
|
||||
|
||||
ecdsa_set_curve(&ecdsa_app);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b2, ec_N2, Gx2, Gy2);
|
||||
ecdsa_set_priv(dec_private);
|
||||
ecdsa_sign_norandom(signbuf->message_hash, sig->r, sig->s);
|
||||
ecdsa_sign(signbuf->message_hash, sig->r, sig->s);
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
@ -696,8 +715,8 @@ int kirk_CMD17(u8* inbuff, int insize)
|
|||
|
||||
if (insize != 0x64) return KIRK_INVALID_SIZE;
|
||||
|
||||
ecdsa_set_curve(&ecdsa_app);
|
||||
ecdsa_set_pub(sig->public_key.x, sig->public_key.y);
|
||||
ecdsa_set_curve(ec_p, ec_a, ec_b2, ec_N2, Gx2, Gy2);
|
||||
ecdsa_set_pub(sig->public_key.x);
|
||||
|
||||
if (ecdsa_verify(sig->message_hash, sig->signature.r, sig->signature.s)) {
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
|
|
|
@ -171,4 +171,24 @@ int kirk_CMD1_ex(void* outbuff, void* inbuff, int size, KIRK_CMD1_HEADER* header
|
|||
int sceUtilsSetFuseID(void*fuse);
|
||||
__declspec(dllexport) int sceUtilsBufferCopyWithRange(void* outbuff, int outsize, void* inbuff, int insize, int cmd);
|
||||
|
||||
/* ECC Curves for Kirk 1 and Kirk 0x11 */
|
||||
// Common Curve paramters p and a
|
||||
static u8 ec_p[0x14] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static u8 ec_a[0x14] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC }; // mon
|
||||
|
||||
// Kirk 0xC,0xD,0x10,0x11,(likely 0x12)- Unique curve parameters for b, N, and base point G for Kirk 0xC,0xD,0x10,0x11,(likely 0x12) service
|
||||
// Since public key is variable, it is not specified here
|
||||
static u8 ec_b2[0x14] = { 0xA6, 0x8B, 0xED, 0xC3, 0x34, 0x18, 0x02, 0x9C, 0x1D, 0x3C, 0xE3, 0x3B, 0x9A, 0x32, 0x1F, 0xCC, 0xBB, 0x9E, 0x0F, 0x0B };// mon
|
||||
static u8 ec_N2[0x15] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xB5, 0xAE, 0x3C, 0x52, 0x3E, 0x63, 0x94, 0x4F, 0x21, 0x27 };
|
||||
static u8 Gx2[0x14] = { 0x12, 0x8E, 0xC4, 0x25, 0x64, 0x87, 0xFD, 0x8F, 0xDF, 0x64, 0xE2, 0x43, 0x7B, 0xC0, 0xA1, 0xF6, 0xD5, 0xAF, 0xDE, 0x2C };
|
||||
static u8 Gy2[0x14] = { 0x59, 0x58, 0x55, 0x7E, 0xB1, 0xDB, 0x00, 0x12, 0x60, 0x42, 0x55, 0x24, 0xDB, 0xC3, 0x79, 0xD5, 0xAC, 0x5F, 0x4A, 0xDF };
|
||||
|
||||
// KIRK 1 - Unique curve parameters for b, N, and base point G
|
||||
// Since public key is hard coded, it is also included
|
||||
static u8 ec_b1[0x14] = { 0x65, 0xD1, 0x48, 0x8C, 0x03, 0x59, 0xE2, 0x34, 0xAD, 0xC9, 0x5B, 0xD3, 0x90, 0x80, 0x14, 0xBD, 0x91, 0xA5, 0x25, 0xF9 };
|
||||
static u8 ec_N1[0x15] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xB5, 0xC6, 0x17, 0xF2, 0x90, 0xEA, 0xE1, 0xDB, 0xAD, 0x8F };
|
||||
static u8 Gx1[0x14] = { 0x22, 0x59, 0xAC, 0xEE, 0x15, 0x48, 0x9C, 0xB0, 0x96, 0xA8, 0x82, 0xF0, 0xAE, 0x1C, 0xF9, 0xFD, 0x8E, 0xE5, 0xF8, 0xFA };
|
||||
static u8 Gy1[0x14] = { 0x60, 0x43, 0x58, 0x45, 0x6D, 0x0A, 0x1C, 0xB2, 0x90, 0x8D, 0xE9, 0x0F, 0x27, 0xD7, 0x5C, 0x82, 0xBE, 0xC1, 0x08, 0xC0 };
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -261,7 +261,7 @@ namespace CHOVY_SIGN
|
|||
BuildPbpThread.Start();
|
||||
while(BuildPbpThread.IsAlive)
|
||||
{
|
||||
if(!Pbp.HasFinished)
|
||||
if (Pbp.DoEvents)
|
||||
{
|
||||
TotalProgress.Maximum = Pbp.NumberOfSectors;
|
||||
TotalProgress.Value = Pbp.SectorsDone;
|
||||
|
|
|
@ -125,8 +125,7 @@ namespace CHOVY_SIGN
|
|||
|
||||
public static int NumberOfSectors = 0;
|
||||
public static int SectorsDone = 0;
|
||||
public static bool HasFinished = false;
|
||||
|
||||
public static bool DoEvents = true;
|
||||
private static UInt32 readUInt32(Stream src)
|
||||
{
|
||||
byte[] intBuf = new byte[0x4];
|
||||
|
@ -217,19 +216,20 @@ namespace CHOVY_SIGN
|
|||
|
||||
pbp.Seek(NPUMDIMGOffest, SeekOrigin.Begin);
|
||||
|
||||
byte[] NP_HEADER = new byte[0x0100];
|
||||
pbp.Read(NP_HEADER, 0x00, 0x0100);
|
||||
byte[] NP_HEADER_ENC = new byte[0x0100];
|
||||
pbp.Read(NP_HEADER_ENC, 0x00, 0x0100);
|
||||
|
||||
byte[] VER_KEY_ENC = new byte[0x40];
|
||||
byte[] NP_HEADER_DEC = new byte[0x40];
|
||||
pbp.Seek(NPUMDIMGOffest+0xC0, SeekOrigin.Begin);
|
||||
pbp.Read(VER_KEY_ENC, 0x00, 0x40);
|
||||
pbp.Read(NP_HEADER_DEC, 0x00, 0x40);
|
||||
|
||||
byte[] VERSION_KEY = new byte[16];
|
||||
|
||||
sceDrmBBMacInit(&mkey, 3);
|
||||
sceDrmBBMacUpdate(&mkey, NP_HEADER, 0xc0);
|
||||
bbmac_getkey(&mkey, VER_KEY_ENC, VERSION_KEY);
|
||||
sceDrmBBMacUpdate(&mkey, NP_HEADER_ENC, 0xc0);
|
||||
bbmac_getkey(&mkey, NP_HEADER_DEC, VERSION_KEY);
|
||||
pbp.Close();
|
||||
|
||||
return VERSION_KEY;
|
||||
}
|
||||
|
||||
|
@ -285,14 +285,16 @@ namespace CHOVY_SIGN
|
|||
|
||||
public static void VerifySignature(bool PS1,byte[] Hash, byte[] Signature)
|
||||
{
|
||||
DoEvents = false;
|
||||
byte[] TestData = new byte[0x64];
|
||||
Array.ConstrainedCopy(npumdimg_public_key, 0, TestData, 0, npumdimg_public_key.Length);
|
||||
Array.ConstrainedCopy(Hash, 0, TestData, npumdimg_public_key.Length, Hash.Length);
|
||||
Array.ConstrainedCopy(Signature, 0, TestData, npumdimg_public_key.Length + Hash.Length, Signature.Length);
|
||||
if (sceUtilsBufferCopyWithRange(null, 0, TestData, 0x64, KIRK_CMD_ECDSA_VERIFY) != 0)
|
||||
if (sceUtilsBufferCopyWithRange(null, 0, TestData, TestData.Length, KIRK_CMD_ECDSA_VERIFY) != 0)
|
||||
{
|
||||
throw new Exception("ECDSA signature for DATA.PSP is invalid!\n");
|
||||
throw new Exception("ECDSA signature for "+BitConverter.ToString(Hash)+" is invalid!\n");
|
||||
}
|
||||
DoEvents = true;
|
||||
}
|
||||
|
||||
public static byte[] BuildDataPsp(byte[] Startdat, string ContentId, byte[] SfoBytes)
|
||||
|
@ -430,16 +432,14 @@ namespace CHOVY_SIGN
|
|||
CIPHER_KEY bck;
|
||||
|
||||
// Encrypt NPUMDIMG body.
|
||||
|
||||
byte[] ToEncrypt = new byte[0x60];
|
||||
Array.ConstrainedCopy(NpumdimgHeader, 0x40, ToEncrypt, 0, ToEncrypt.Length);
|
||||
sceDrmBBCipherInit(&bck, 1, 2, header_key, version_key, 0);
|
||||
sceDrmBBCipherUpdate(&bck, ToEncrypt, 0x60);
|
||||
sceDrmBBCipherFinal(&bck);
|
||||
|
||||
|
||||
Array.ConstrainedCopy(ToEncrypt, 0x00, NpumdimgHeader, 0x40, ToEncrypt.Length);
|
||||
|
||||
|
||||
// Generate header hash.
|
||||
byte[] header_hash = new byte[0x10];
|
||||
|
||||
|
@ -513,7 +513,7 @@ namespace CHOVY_SIGN
|
|||
|
||||
// Generate Random Header Key
|
||||
byte[] HeaderKey = new byte[0x10];
|
||||
sceUtilsBufferCopyWithRange(HeaderKey, HeaderKey.Length, null, 0, KIRK_CMD_PRNG);
|
||||
//sceUtilsBufferCopyWithRange(HeaderKey, HeaderKey.Length, null, 0, KIRK_CMD_PRNG);
|
||||
|
||||
byte[] TableBuffer = new byte[TableSize];
|
||||
DataUtils.WriteBytes(BaseStr, TableBuffer, TableSize);
|
||||
|
@ -567,6 +567,7 @@ namespace CHOVY_SIGN
|
|||
DataUtils.CopyInt32(Tb, 0, 0x1C);
|
||||
|
||||
// Encrypt Block
|
||||
|
||||
sceDrmBBCipherInit(&CKey, 1, 2, HeaderKey, VersionKey, Convert.ToUInt32((IsoOffset >> 4)));
|
||||
if(!Compress)
|
||||
sceDrmBBCipherUpdate(&CKey, IsoBuffer, WSize);
|
||||
|
@ -574,6 +575,7 @@ namespace CHOVY_SIGN
|
|||
sceDrmBBCipherUpdate(&CKey, LZRCBuffer, WSize);
|
||||
sceDrmBBCipherFinal(&CKey);
|
||||
|
||||
|
||||
// Build MAC.
|
||||
sceDrmBBMacInit(&MKey, 3);
|
||||
if (!Compress)
|
||||
|
@ -599,9 +601,9 @@ namespace CHOVY_SIGN
|
|||
|
||||
// Copy TB Back
|
||||
Array.ConstrainedCopy(EncTb, 0, TableBuffer, TbOffset, EncTb.Length);
|
||||
//Array.ConstrainedCopy(Tb, 0, TableBuffer, TbOffset, Tb.Length);
|
||||
|
||||
}
|
||||
HasFinished = true;
|
||||
// Generate data key.
|
||||
byte[] DataKey = new byte[0x10];
|
||||
sceDrmBBMacInit(&MKey, 3);
|
||||
|
@ -648,6 +650,8 @@ namespace CHOVY_SIGN
|
|||
}
|
||||
public static void BuildPbp(Stream Str, Stream Iso, bool Compress, byte[] VersionKey, Bitmap start_image, string content_id, byte[] param_sfo,byte[] icon0, byte[] icon1pmf, byte[] pic0, byte[] pic1, byte[] sndat3)
|
||||
{
|
||||
|
||||
DoEvents = true;
|
||||
kirk_init();
|
||||
|
||||
byte[] NewSfo = PatchSfo(param_sfo, content_id);
|
||||
|
@ -726,12 +730,12 @@ namespace CHOVY_SIGN
|
|||
Str.Write(DataPsar, 0x00, DataPsar.Length);
|
||||
OffsetToWrite += DataPsar.Length;
|
||||
|
||||
|
||||
// Sign ISO Contents.
|
||||
SignIso(OffsetToWrite, Str, Iso, content_id, VersionKey, Compress);
|
||||
|
||||
NumberOfSectors = 0;
|
||||
SectorsDone = 0;
|
||||
HasFinished = false;
|
||||
}
|
||||
public static int gen__sce_ebootpbp(string EbootFile, UInt64 AID, string OutSceebootpbpFile)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue