commit the experimental GCM/AES stuff in the engine
This commit is contained in:
@@ -87,7 +87,7 @@ struct sbusfpga_curve25519engine_montgomeryjob {
|
||||
uint32_t scalar[8];
|
||||
};
|
||||
|
||||
static int init_program(struct sbusfpga_curve25519engine_softc *sc);
|
||||
static int init_programs(struct sbusfpga_curve25519engine_softc *sc);
|
||||
static int write_inputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusfpga_curve25519engine_montgomeryjob *job, const int window);
|
||||
static int start_job(struct sbusfpga_curve25519engine_softc *sc);
|
||||
static int wait_job(struct sbusfpga_curve25519engine_softc *sc);
|
||||
@@ -96,47 +96,6 @@ static int read_outputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusf
|
||||
static int power_on(struct sbusfpga_curve25519engine_softc *sc);
|
||||
static int power_off(struct sbusfpga_curve25519engine_softc *sc);
|
||||
|
||||
#define SBUSFPGA_DO_MONTGOMERYJOB _IOWR(0, 0, struct sbusfpga_curve25519engine_montgomeryjob)
|
||||
|
||||
int
|
||||
sbusfpga_curve25519engine_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||
{
|
||||
struct sbusfpga_curve25519engine_softc *sc = device_lookup_private(&sbusfpga_c29e_cd, minor(dev));
|
||||
struct sbusfpga_curve25519engine_montgomeryjob* job = (struct sbusfpga_curve25519engine_montgomeryjob*)data;
|
||||
int err = 0;
|
||||
|
||||
if (!sc->initialized) {
|
||||
if (init_program(sc)) {
|
||||
return ENXIO;
|
||||
} else {
|
||||
sc->initialized = 1;
|
||||
}
|
||||
}
|
||||
switch (cmd) {
|
||||
case SBUSFPGA_DO_MONTGOMERYJOB: {
|
||||
err = write_inputs(sc, job, 0);
|
||||
if (err)
|
||||
return err;
|
||||
err = start_job(sc);
|
||||
if (err)
|
||||
return err;
|
||||
delay(1);
|
||||
err = wait_job(sc);
|
||||
if (err)
|
||||
return err;
|
||||
err = read_outputs(sc, job, 0);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
int
|
||||
sbusfpga_curve25519engine_open(dev_t dev, int flags, int mode, struct lwp *l)
|
||||
{
|
||||
@@ -172,8 +131,14 @@ sbusfpga_curve25519engine_match(device_t parent, cfdata_t cf, void *aux)
|
||||
return (strcmp("betrustedc25519e", sa->sa_name) == 0);
|
||||
}
|
||||
|
||||
static const uint32_t program[192] = {0x00640840, 0x00680800, 0x006c0600, 0x00700840, 0x004c0a80, 0x00480800, 0x007407cc, 0x007c07cb, 0x0049d483, 0x0079b643, 0x0079e482, 0x00659783, 0x006db783, 0x0079c683, 0x0079e482, 0x0069a783, 0x0071c783, 0x00480740, 0x0001a645, 0x00780008, 0x0001e006, 0x0069a8c6, 0x0005a645, 0x00780048, 0x0005e046, 0x0009c6c5, 0x00780088, 0x0009e086, 0x0071c8c6, 0x000dc6c5, 0x007800c8, 0x000de0c6, 0x00100007, 0x00141047, 0x007458c6, 0x0019d105, 0x00780188, 0x0019e186, 0x001c3007, 0x00202047, 0x002481c5, 0x00780248, 0x0025e246, 0x007488c6, 0x0029d1c5, 0x00780288, 0x0029e286, 0x006c9247, 0x0030a287, 0x00346907, 0x00645107, 0x003c5345, 0x007803c8, 0x003de3c6, 0x0068f187, 0x0070c607, 0x010004c9, 0x004e14c6, 0xe5800809, 0x0079b643, 0x0079e482, 0x00659783, 0x006db783, 0x0079c683, 0x0079e482, 0x0069a783, 0x0071c783, 0x00740640, 0x00780680, 0x0001e787, 0x00040007, 0x00041047, 0x00081787, 0x000c2007, 0x001030c7, 0x00144087, 0x00700940, 0x00185147, 0x00721706, 0x01000709, 0x00186187, 0xfe000809, 0x001c5187, 0x00700980, 0x002071c7, 0x00721706, 0x01000709, 0x00208207, 0xfe000809, 0x00247207, 0x007009c0, 0x00289247, 0x00721706, 0x01000709, 0x0028a287, 0xfe000809, 0x002c9287, 0x00700980, 0x0030b2c7, 0x00721706, 0x01000709, 0x0030c307, 0xfe000809, 0x00347307, 0x00700a00, 0x0038d347, 0x00721706, 0x01000709, 0x0038e387, 0xfe000809, 0x003cd387, 0x00700a40, 0x0040f3c7, 0x00721706, 0x01000709, 0x00410407, 0xfe000809, 0x0044f407, 0x00700a00, 0x00491447, 0x00721706, 0x01000709, 0x00492487, 0xfe000809, 0x004cd487, 0x00700940, 0x005134c7, 0x00721706, 0x01000709, 0x00514507, 0xfe000809, 0x00543507, 0x007d5747, 0x0000000a, 0x0000000a, 0x0000000a};
|
||||
static const uint32_t program_len = 134;
|
||||
static const uint32_t program_ec25519[134] = {0x00640840, 0x00680800, 0x006c0600, 0x00700840, 0x004c0a80, 0x00480800, 0x007407cc, 0x007c07cb, 0x0049d483, 0x0079b643, 0x0079e482, 0x00659783, 0x006db783, 0x0079c683, 0x0079e482, 0x0069a783, 0x0071c783, 0x00480740, 0x0001a645, 0x00780008, 0x0001e006, 0x0069a8c6, 0x0005a645, 0x00780048, 0x0005e046, 0x0009c6c5, 0x00780088, 0x0009e086, 0x0071c8c6, 0x000dc6c5, 0x007800c8, 0x000de0c6, 0x00100007, 0x00141047, 0x007458c6, 0x0019d105, 0x00780188, 0x0019e186, 0x001c3007, 0x00202047, 0x002481c5, 0x00780248, 0x0025e246, 0x007488c6, 0x0029d1c5, 0x00780288, 0x0029e286, 0x006c9247, 0x0030a287, 0x00346907, 0x00645107, 0x003c5345, 0x007803c8, 0x003de3c6, 0x0068f187, 0x0070c607, 0x010004c9, 0x004e14c6, 0xe5800809, 0x0079b643, 0x0079e482, 0x00659783, 0x006db783, 0x0079c683, 0x0079e482, 0x0069a783, 0x0071c783, 0x00740640, 0x00780680, 0x0001e787, 0x00040007, 0x00041047, 0x00081787, 0x000c2007, 0x001030c7, 0x00144087, 0x00700940, 0x00185147, 0x00721706, 0x01000709, 0x00186187, 0xfe000809, 0x001c5187, 0x00700980, 0x002071c7, 0x00721706, 0x01000709, 0x00208207, 0xfe000809, 0x00247207, 0x007009c0, 0x00289247, 0x00721706, 0x01000709, 0x0028a287, 0xfe000809, 0x002c9287, 0x00700980, 0x0030b2c7, 0x00721706, 0x01000709, 0x0030c307, 0xfe000809, 0x00347307, 0x00700a00, 0x0038d347, 0x00721706, 0x01000709, 0x0038e387, 0xfe000809, 0x003cd387, 0x00700a40, 0x0040f3c7, 0x00721706, 0x01000709, 0x00410407, 0xfe000809, 0x0044f407, 0x00700a00, 0x00491447, 0x00721706, 0x01000709, 0x00492487, 0xfe000809, 0x004cd487, 0x00700940, 0x005134c7, 0x00721706, 0x01000709, 0x00514507, 0xfe000809, 0x00543507, 0x007d5747, 0x0000000a };
|
||||
|
||||
static const uint32_t program_gcm[20] = {0x0010100d, 0x0094100d, 0x0118100d, 0x019c100d, 0x00186143, 0x00160191, 0x00186811, 0x001c61c3, 0x00105103, 0x008441ce, 0x0082010e, 0x00080010, 0x008e008f, 0x0112008f, 0x0396008f, 0x00083083, 0x00105103, 0x00084083, 0x00001083, 0x0000000a };
|
||||
static const uint32_t program_aes[21] = {0x00000052, 0x00800052, 0x01000052, 0x01800052, 0x0000000a };
|
||||
|
||||
static const uint32_t* programs[4] = { program_ec25519, program_gcm, program_aes, NULL };
|
||||
static const uint32_t program_len[4] = { 134, 20, 5, 0 };
|
||||
static uint32_t program_offset[4];
|
||||
|
||||
/*
|
||||
* Attach all the sub-devices we can find
|
||||
@@ -265,8 +230,8 @@ sbusfpga_curve25519engine_attach(device_t parent, device_t self, void *aux)
|
||||
/* first we need to turn the engine power on ... */
|
||||
power_on(sc);
|
||||
|
||||
if (init_program(sc)) {
|
||||
if (init_program(sc)) {
|
||||
if (init_programs(sc)) {
|
||||
if (init_programs(sc)) {
|
||||
aprint_normal_dev(sc->sc_dev, "INIT - FAILED\n");
|
||||
sc->initialized = 0;
|
||||
} else {
|
||||
@@ -307,6 +272,120 @@ sbusfpga_curve25519engine_attach(device_t parent, device_t self, void *aux)
|
||||
#undef CSR_SDPHY_BASE
|
||||
#undef CSR_TRNG_BASE
|
||||
|
||||
#define REG_BASE(reg) (base + (reg * 32))
|
||||
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
|
||||
|
||||
#define SBUSFPGA_DO_MONTGOMERYJOB _IOWR(0, 0, struct sbusfpga_curve25519engine_montgomeryjob)
|
||||
#define SBUSFPGA_EC25519_CHECKGCM _IOW(0, 1, struct sbusfpga_curve25519engine_montgomeryjob)
|
||||
#define SBUSFPGA_EC25519_CHECKAES _IOW(0, 2, struct sbusfpga_curve25519engine_montgomeryjob)
|
||||
|
||||
int
|
||||
sbusfpga_curve25519engine_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||
{
|
||||
struct sbusfpga_curve25519engine_softc *sc = device_lookup_private(&sbusfpga_c29e_cd, minor(dev));
|
||||
int err = 0;
|
||||
|
||||
if (!sc->initialized) {
|
||||
if (init_programs(sc)) {
|
||||
return ENXIO;
|
||||
} else {
|
||||
sc->initialized = 1;
|
||||
}
|
||||
}
|
||||
switch (cmd) {
|
||||
case SBUSFPGA_DO_MONTGOMERYJOB: {
|
||||
struct sbusfpga_curve25519engine_montgomeryjob* job = (struct sbusfpga_curve25519engine_montgomeryjob*)data;
|
||||
curve25519engine_mpstart_write(sc, program_offset[0]); /* EC25519 */
|
||||
curve25519engine_mplen_write(sc, program_len[0]); /* EC25519 */
|
||||
|
||||
err = write_inputs(sc, job, 0);
|
||||
if (err)
|
||||
return err;
|
||||
err = start_job(sc);
|
||||
if (err)
|
||||
return err;
|
||||
delay(1);
|
||||
err = wait_job(sc);
|
||||
if (err)
|
||||
return err;
|
||||
err = read_outputs(sc, job, 0);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case SBUSFPGA_EC25519_CHECKGCM: {
|
||||
const uint32_t base = 0;
|
||||
struct sbusfpga_curve25519engine_montgomeryjob* job = (struct sbusfpga_curve25519engine_montgomeryjob*)data;
|
||||
int reg, i;
|
||||
|
||||
curve25519engine_mpstart_write(sc, program_offset[1]); /* GCM */
|
||||
curve25519engine_mplen_write(sc, program_len[1]); /* GCM */
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,i), job->affine_u[i]);
|
||||
}
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(1,i), job->scalar[i]);
|
||||
}
|
||||
|
||||
err = start_job(sc);
|
||||
if (err)
|
||||
return err;
|
||||
delay(1);
|
||||
err = wait_job(sc);
|
||||
/* if (err) */
|
||||
/* return err; */
|
||||
|
||||
for (reg = 0 ; reg < 32 ; reg++) {
|
||||
uint32_t buf[8];
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
buf[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(reg,i));
|
||||
}
|
||||
device_printf(sc->sc_dev, "GCM %d: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n", reg,
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SBUSFPGA_EC25519_CHECKAES: {
|
||||
const uint32_t base = 0;
|
||||
struct sbusfpga_curve25519engine_montgomeryjob* job = (struct sbusfpga_curve25519engine_montgomeryjob*)data;
|
||||
int reg, i;
|
||||
|
||||
curve25519engine_mpstart_write(sc, program_offset[2]); /* AES */
|
||||
curve25519engine_mplen_write(sc, program_len[2]); /* AES */
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,i), job->affine_u[i]);
|
||||
}
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(1,i), job->scalar[i]);
|
||||
}
|
||||
|
||||
err = start_job(sc);
|
||||
if (err)
|
||||
return err;
|
||||
delay(1);
|
||||
err = wait_job(sc);
|
||||
/* if (err) */
|
||||
/* return err; */
|
||||
|
||||
for (reg = 0 ; reg < 32 ; reg++) {
|
||||
uint32_t buf[8];
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
buf[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(reg,i));
|
||||
}
|
||||
device_printf(sc->sc_dev, "AES %d: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n", reg,
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
static int power_on(struct sbusfpga_curve25519engine_softc *sc) {
|
||||
int err = 0;
|
||||
if ((curve25519engine_power_read(sc) & 1) == 0) {
|
||||
@@ -321,20 +400,25 @@ static int power_off(struct sbusfpga_curve25519engine_softc *sc) {
|
||||
return err;
|
||||
}
|
||||
|
||||
static int init_program(struct sbusfpga_curve25519engine_softc *sc) {
|
||||
static int init_programs(struct sbusfpga_curve25519engine_softc *sc) {
|
||||
/* the microcode is a the beginning */
|
||||
int err = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0 ; i < program_len + 1 ; i++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_microcode, (i*4), program[i]);
|
||||
if ((i%16)==15)
|
||||
delay(1);
|
||||
uint32_t i, j;
|
||||
uint32_t offset = 0;
|
||||
|
||||
for (j = 0 ; programs[j] != NULL; j ++) {
|
||||
program_offset[j] = offset;
|
||||
for (i = 0 ; i < program_len[j] ; i++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_microcode, ((offset+i)*4), programs[j][i]);
|
||||
if ((i%16)==15)
|
||||
delay(1);
|
||||
}
|
||||
offset += program_len[j];
|
||||
}
|
||||
|
||||
curve25519engine_window_write(sc, 0); /* could use window_window to access fields, but it creates a RMW cycle for nothing */
|
||||
curve25519engine_mpstart_write(sc, 0);
|
||||
curve25519engine_mplen_write(sc, program_len);
|
||||
curve25519engine_mpstart_write(sc, 0); /* EC25519 */
|
||||
curve25519engine_mplen_write(sc, program_len[0]); /* EC25519 */
|
||||
|
||||
aprint_normal_dev(sc->sc_dev, "INIT - Curve25519Engine status: 0x%08x\n", curve25519engine_status_read(sc));
|
||||
|
||||
@@ -342,10 +426,10 @@ static int init_program(struct sbusfpga_curve25519engine_softc *sc) {
|
||||
/* double check */
|
||||
u_int32_t x;
|
||||
int count = 0;
|
||||
for (i = 0 ; i < program_len + 1 && count < 10; i++) {
|
||||
for (i = 0 ; i < program_len[0] && count < 10; i++) {
|
||||
x = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_microcode, (i*4));
|
||||
if (x != program[i]) {
|
||||
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine program failure: [%d] 0x%08x <> 0x%08x\n", i, x, program[i]);
|
||||
if (x != programs[0][i]) {
|
||||
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine program failure: [%d] 0x%08x <> 0x%08x\n", i, x, programs[0][i]);
|
||||
err = 1;
|
||||
count ++;
|
||||
}
|
||||
@@ -360,7 +444,7 @@ static int init_program(struct sbusfpga_curve25519engine_softc *sc) {
|
||||
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine register failure: mpstart = 0x%08x\n", x);
|
||||
err = 1;
|
||||
}
|
||||
if ((x = curve25519engine_mplen_read(sc)) != program_len) {
|
||||
if ((x = curve25519engine_mplen_read(sc)) != program_len[0]) {
|
||||
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine register failure: mplen = 0x%08x\n", x);
|
||||
err = 1;
|
||||
}
|
||||
@@ -386,9 +470,6 @@ static int write_inputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusf
|
||||
aprint_error_dev(sc->sc_dev, "WRITE - Curve25519Engine status: 0x%08x, still running?\n", status);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
#define REG_BASE(reg) (base + (reg * 32))
|
||||
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(24,i), job->affine_u[i]);
|
||||
/* bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(25,i), job->x0_u[i]); */
|
||||
@@ -399,12 +480,8 @@ static int write_inputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusf
|
||||
/* bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(19,i), ((i == 0) ? 254 : 0)); */
|
||||
/* delay(1); */
|
||||
}
|
||||
#undef SUBREG_ADDR
|
||||
#undef REG_BASE
|
||||
|
||||
#if 1
|
||||
#define REG_BASE(reg) (base + (reg * 32))
|
||||
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
|
||||
for (i = 0 ; i < 8 && !err; i ++) {
|
||||
if (job->affine_u[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(24,i))) err = EIO;
|
||||
/* if (job->x0_u[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(25,i))) err = EIO; */
|
||||
@@ -415,8 +492,6 @@ static int write_inputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusf
|
||||
/* delay(1); */
|
||||
}
|
||||
if (err) aprint_error_dev(sc->sc_dev, "WRITE - data did not read-write properly\n");
|
||||
#undef SUBREG_ADDR
|
||||
#undef REG_BASE
|
||||
#endif
|
||||
|
||||
return err;
|
||||
@@ -463,8 +538,6 @@ static int read_outputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusf
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
#define REG_BASE(reg) (base + (reg * 32))
|
||||
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
|
||||
for (i = 0 ; i < 8 ; i ++) {
|
||||
/* job->affine_u[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(24,i)); */
|
||||
/* job->x0_u[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(25,i)); */
|
||||
@@ -475,8 +548,6 @@ static int read_outputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusf
|
||||
/* delay(1); */
|
||||
}
|
||||
aprint_normal_dev(sc->sc_dev, "READ - Curve25519Engine 19 low 32 bits: 0x%08x\n", bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(19,0)));
|
||||
#undef SUBREG_ADDR
|
||||
#undef REG_BASE
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user