Implement --bsl-entry-password option.

This commit is contained in:
Daniel Beer 2019-03-08 08:46:16 +13:00
parent 3bc5cb2686
commit 989038d3b3
5 changed files with 76 additions and 11 deletions

View File

@ -86,6 +86,7 @@ struct device_args {
int bsl_gpio_used; int bsl_gpio_used;
int bsl_gpio_rts; int bsl_gpio_rts;
int bsl_gpio_dtr; int bsl_gpio_dtr;
uint8_t bsl_entry_password[32];
}; };
struct device_class { struct device_class {

View File

@ -384,7 +384,8 @@ static int flash_bsl_erase(device_t dev_base, device_erase_type_t type,
return 0; return 0;
} }
static int flash_bsl_unlock(struct flash_bsl_device *dev) static int flash_bsl_unlock(struct flash_bsl_device *dev,
const uint8_t *password)
{ {
/* /*
* after erase, the password will be 0xff * (16 or 32) * after erase, the password will be 0xff * (16 or 32)
@ -401,6 +402,8 @@ static int flash_bsl_unlock(struct flash_bsl_device *dev)
uint8_t response_buffer[16]; uint8_t response_buffer[16];
int ret; int ret;
memcpy(rx_password_cmd + 1, password, 32);
/* mass erase - this might wipe Information Memory on some devices */ /* mass erase - this might wipe Information Memory on some devices */
/* (according to the documentation it should not) */ /* (according to the documentation it should not) */
if (flash_bsl_erase((device_t)dev, DEVICE_ERASE_MAIN, 0) < 0) { if (flash_bsl_erase((device_t)dev, DEVICE_ERASE_MAIN, 0) < 0) {
@ -625,7 +628,7 @@ static device_t flash_bsl_open(const struct device_args *args)
delay_ms(500); delay_ms(500);
/* unlock device (erase then send password) */ /* unlock device (erase then send password) */
if (flash_bsl_unlock(dev) < 0) { if (flash_bsl_unlock(dev, args->bsl_entry_password) < 0) {
goto fail; goto fail;
} }

View File

@ -404,15 +404,9 @@ static int rom_bsl_erase(device_t dev_base, device_erase_type_t type,
return 0; return 0;
} }
static int unlock_device(struct rom_bsl_device *dev) static int unlock_device(struct rom_bsl_device *dev,
const uint8_t *password)
{ {
const static uint8_t password[32] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
printc_dbg("Performing mass erase...\n"); printc_dbg("Performing mass erase...\n");
if (rom_bsl_xfer(dev, CMD_MASS_ERASE, 0xfffe, NULL, 0xa506) < 0) { if (rom_bsl_xfer(dev, CMD_MASS_ERASE, 0xfffe, NULL, 0xa506) < 0) {
@ -488,7 +482,7 @@ static device_t rom_bsl_open(const struct device_args *args)
dev->reply_buf[15], dev->reply_buf[15],
dev->reply_buf[16]); dev->reply_buf[16]);
if (unlock_device(dev) < 0) { if (unlock_device(dev, args->bsl_entry_password) < 0) {
printc_err("rom_bsl: failed to unlock\n"); printc_err("rom_bsl: failed to unlock\n");
goto fail; goto fail;
} }

View File

@ -100,6 +100,11 @@ line transition (R: RTS on, r: RTS off, D: DTR on, d: DTR off). A comma
indicates a delay. The entry and exit sequences are separated by a indicates a delay. The entry and exit sequences are separated by a
colon. The default value is \fBdR,r,R,r,R,D:dR,DR\fR, for the colon. The default value is \fBdR,r,R,r,R,D:dR,DR\fR, for the
\fBflash-bsl\fR driver. \fBflash-bsl\fR driver.
.IP "\-\-bsl\-entry\-password \fIhex\-string\fR"
Specify a BSL unlock password as a hexadecimal byte string. This
option affects both the flash and ROM BSL drivers. The password will
be padded with 0xff bytes, and the default password is a sequence
consisting of only 0xff bytes.
.SH DRIVERS .SH DRIVERS
For drivers supporting both USB and tty access, USB is the default, For drivers supporting both USB and tty access, USB is the default,
unless specified otherwise (see \fB-d\fR above). unless specified otherwise (see \fB-d\fR above).

View File

@ -154,6 +154,8 @@ static void usage(const char *progname)
" On some host (say RaspberryPi) defines a GPIO pin# to be used as RTS\n" " On some host (say RaspberryPi) defines a GPIO pin# to be used as RTS\n"
" --bsl-gpio-dtr\n" " --bsl-gpio-dtr\n"
" On some host (say RaspberryPi) defines a GPIO pin# to be used as DTR\n" " On some host (say RaspberryPi) defines a GPIO pin# to be used as DTR\n"
" --bsl-entry-password <hex string>\n"
" Use the given hex byte string as a BSL entry password.\n"
"\n" "\n"
"Most drivers connect by default via USB, unless told otherwise via the\n" "Most drivers connect by default via USB, unless told otherwise via the\n"
"-d option. By default, the first USB device found is opened.\n" "-d option. By default, the first USB device found is opened.\n"
@ -170,6 +172,51 @@ static void usage(const char *progname)
} }
} }
static int parse_hex_string(uint8_t *buf, size_t len, const char *text)
{
unsigned int ptr = 0;
uint8_t b = 0;
while (*text) {
char d = *(text++);
int digit = 0;
if (d >= '0' && d <= '9')
digit = d - '0';
else if (d >= 'A' && d <= 'F')
digit = d - 'A' + 10;
else if (d >= 'a' && d <= 'f')
digit = d - 'a' + 10;
else {
fprintf(stderr, "invalid hex digit: %c\n", d);
return -1;
}
b = (b << 4) | digit;
ptr++;
if (!(ptr & 1)) {
unsigned int pos = (ptr >> 1) - 1;
if (pos >= len) {
fprintf(stderr,
"maximum length exceeded (%d)\n",
(int)len);
return -1;
}
buf[pos] = b;
}
}
if (ptr & 1) {
fprintf(stderr, "odd number of hex digits encountered\n");
return -1;
}
return 0;
}
static void process_rc_file(const char *config) static void process_rc_file(const char *config)
{ {
char text[256]; char text[256];
@ -255,6 +302,7 @@ static int parse_cmdline_args(int argc, char **argv,
LOPT_BSL_ENTRY_SEQUENCE, LOPT_BSL_ENTRY_SEQUENCE,
LOPT_BSL_GPIO_RTS, LOPT_BSL_GPIO_RTS,
LOPT_BSL_GPIO_DTR, LOPT_BSL_GPIO_DTR,
LOPT_BSL_ENTRY_PASSWORD,
}; };
static const struct option longopts[] = { static const struct option longopts[] = {
@ -272,6 +320,7 @@ static int parse_cmdline_args(int argc, char **argv,
{"bsl-entry-sequence", 1, 0, LOPT_BSL_ENTRY_SEQUENCE}, {"bsl-entry-sequence", 1, 0, LOPT_BSL_ENTRY_SEQUENCE},
{"bsl-gpio-rts", 1, 0, LOPT_BSL_GPIO_RTS}, {"bsl-gpio-rts", 1, 0, LOPT_BSL_GPIO_RTS},
{"bsl-gpio-dtr", 1, 0, LOPT_BSL_GPIO_DTR}, {"bsl-gpio-dtr", 1, 0, LOPT_BSL_GPIO_DTR},
{"bsl-entry-password", 1, 0, LOPT_BSL_ENTRY_PASSWORD},
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
@ -295,6 +344,16 @@ static int parse_cmdline_args(int argc, char **argv,
} }
break; break;
case LOPT_BSL_ENTRY_PASSWORD:
if (parse_hex_string
(args->devarg.bsl_entry_password,
sizeof(args->devarg.bsl_entry_password),
optarg) < 0) {
fprintf(stderr, "invalid BSL password\n");
return -1;
}
break;
case LOPT_BSL_ENTRY_SEQUENCE: case LOPT_BSL_ENTRY_SEQUENCE:
args->devarg.bsl_entry_seq = optarg; args->devarg.bsl_entry_seq = optarg;
break; break;
@ -465,6 +524,9 @@ int main(int argc, char **argv)
args.devarg.vcc_mv = 3000; args.devarg.vcc_mv = 3000;
args.devarg.requested_serial = NULL; args.devarg.requested_serial = NULL;
memset(args.devarg.bsl_entry_password, 0xff,
sizeof(args.devarg.bsl_entry_password));
if (parse_cmdline_args(argc, argv, &args) < 0) if (parse_cmdline_args(argc, argv, &args) < 0)
goto fail_parse; goto fail_parse;