From: Simon Glass <simon.glass@canonical.com> When unlocking an encrypted disk with a TKey we need a few more UI operations: - allow the password-entry textline to be shown/hidden - allow showing instructions to the user, as well as unlock result - obtain the password entered by the user Add these to the API and implement them in the multi UI. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/bootctl/multi_ui.c | 84 +++++++++++++++++++++++++++++++++++++++++ boot/bootctl/util.c | 60 +++++++++++++++++++++++++++++ include/bootctl/ui.h | 80 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+) diff --git a/boot/bootctl/multi_ui.c b/boot/bootctl/multi_ui.c index f4f0bd281fe..5145e4357cb 100644 --- a/boot/bootctl/multi_ui.c +++ b/boot/bootctl/multi_ui.c @@ -577,6 +577,86 @@ static int multiboot_ui_of_to_plat(struct udevice *dev) return 0; } +static int multiboot_ui_show_pass(struct udevice *dev, int seq, bool show) +{ + struct bc_ui_priv *upriv = dev_get_uclass_priv(dev); + struct scene *scn = upriv->scn; + int ret; + + scene_obj_set_hide(scn, ITEM_PASS + seq, !show); + scene_obj_set_hide(scn, ITEM_PASS_LABEL + seq, !show); + scene_obj_set_hide(scn, ITEM_PASS_EDIT + seq, !show); + + if (show) { + struct scene_obj_textline *tline; + char *buf; + + /* Clear the passphrase buffer for retry */ + tline = scene_obj_find(scn, ITEM_PASS + seq, + SCENEOBJT_TEXTLINE); + if (!tline) + return log_msg_ret("tln", -ENOENT); + buf = abuf_data(&tline->buf); + *buf = '\0'; + + /* Set highlight and open the textline for editing */ + scene_set_highlight_id(scn, ITEM_PASS + seq); + ret = scene_set_open(scn, ITEM_PASS + seq, true); + if (ret) + return log_msg_ret("sop", ret); + } else { + /* Close the textline */ + ret = scene_set_open(scn, ITEM_PASS + seq, false); + if (ret) + return log_msg_ret("sop", ret); + } + + return 0; +} + +static int multiboot_ui_get_pass(struct udevice *dev, int seq, + const char **passp) +{ + struct bc_ui_priv *upriv = dev_get_uclass_priv(dev); + struct scene *scn = upriv->scn; + struct scene_obj_textline *tline; + + tline = scene_obj_find(scn, ITEM_PASS + seq, SCENEOBJT_TEXTLINE); + if (!tline) + return log_msg_ret("tln", -ENOENT); + + *passp = abuf_data(&tline->buf); + + return 0; +} + +static int multiboot_ui_show_pass_msg(struct udevice *dev, int seq, bool show) +{ + struct bc_ui_priv *upriv = dev_get_uclass_priv(dev); + struct scene *scn = upriv->scn; + + scene_obj_set_hide(scn, ITEM_PASS_MSG + seq, !show); + + return 0; +} + +static int multiboot_ui_set_pass_msg(struct udevice *dev, int seq, + const char *msg) +{ + struct bc_ui_priv *upriv = dev_get_uclass_priv(dev); + struct expo *exp = upriv->expo; + struct abuf *buf; + int ret; + + ret = expo_edit_str(exp, STR_PASS_MSG + seq, NULL, &buf); + if (ret) + return log_msg_ret("spm", ret); + + abuf_set(buf, (void *)msg, strlen(msg) + 1); + + return 0; +} + static struct bc_ui_ops ops = { .print = multiboot_ui_print, .show = multiboot_ui_show, @@ -584,6 +664,10 @@ static struct bc_ui_ops ops = { .render = multiboot_ui_render, .poll = multiboot_ui_poll, .switch_layout = multiboot_ui_switch_layout, + .show_pass = multiboot_ui_show_pass, + .get_pass = multiboot_ui_get_pass, + .show_pass_msg = multiboot_ui_show_pass_msg, + .set_pass_msg = multiboot_ui_set_pass_msg, }; static const struct udevice_id multiboot_ui_ids[] = { diff --git a/boot/bootctl/util.c b/boot/bootctl/util.c index 48912c67f21..790489ca937 100644 --- a/boot/bootctl/util.c +++ b/boot/bootctl/util.c @@ -110,6 +110,66 @@ int bc_ui_switch_layout(struct udevice *dev) return 0; } +int bc_ui_show_pass(struct udevice *dev, int seq, bool show) +{ + struct bc_ui_ops *ops = bc_ui_get_ops(dev); + int ret; + + if (!ops->show_pass) + return -ENOSYS; + + ret = ops->show_pass(dev, seq, show); + if (ret) + return log_msg_ret("bsp", ret); + + return 0; +} + +int bc_ui_get_pass(struct udevice *dev, int seq, const char **passp) +{ + struct bc_ui_ops *ops = bc_ui_get_ops(dev); + int ret; + + if (!ops->get_pass) + return -ENOSYS; + + ret = ops->get_pass(dev, seq, passp); + if (ret) + return log_msg_ret("bgp", ret); + + return 0; +} + +int bc_ui_show_pass_msg(struct udevice *dev, int seq, bool show) +{ + struct bc_ui_ops *ops = bc_ui_get_ops(dev); + int ret; + + if (!ops->show_pass_msg) + return -ENOSYS; + + ret = ops->show_pass_msg(dev, seq, show); + if (ret) + return log_msg_ret("bse", ret); + + return 0; +} + +int bc_ui_set_pass_msg(struct udevice *dev, int seq, const char *msg) +{ + struct bc_ui_ops *ops = bc_ui_get_ops(dev); + int ret; + + if (!ops->set_pass_msg) + return -ENOSYS; + + ret = ops->set_pass_msg(dev, seq, msg); + if (ret) + return log_msg_ret("bsm", ret); + + return 0; +} + void bc_oslist_setup_iter(struct oslist_iter *iter) { memset(iter, '\0', sizeof(struct oslist_iter)); diff --git a/include/bootctl/ui.h b/include/bootctl/ui.h index 4f8e08a00c2..5e592e3dce2 100644 --- a/include/bootctl/ui.h +++ b/include/bootctl/ui.h @@ -99,6 +99,46 @@ struct bc_ui_ops { * Return 0 if OK, -ve on error */ int (*switch_layout)(struct udevice *dev); + + /** + * show_pass() - Show or hide the passphrase input field + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @show: true to show the pass field, false to hide it + * Return 0 if OK, -ve on error + */ + int (*show_pass)(struct udevice *dev, int seq, bool show); + + /** + * get_pass() - Get the passphrase entered by the user + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @passp: Returns pointer to the passphrase string + * Return 0 if OK, -ve on error + */ + int (*get_pass)(struct udevice *dev, int seq, const char **passp); + + /** + * show_pass_msg() - Show or hide the pass message + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @show: true to show the message, false to hide it + * Return 0 if OK, -ve on error + */ + int (*show_pass_msg)(struct udevice *dev, int seq, bool show); + + /** + * set_pass_msg() - Set the pass message text + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @msg: Message text to display + * Return 0 if OK, -ve on error + */ + int (*set_pass_msg)(struct udevice *dev, int seq, const char *msg); }; #define bc_ui_get_ops(dev) ((struct bc_ui_ops *)(dev)->driver->ops) @@ -148,4 +188,44 @@ int bc_ui_poll(struct udevice *dev, int *seqp, bool *selectedp); */ int bc_ui_switch_layout(struct udevice *dev); +/** + * bc_ui_show_pass() - Show or hide the pass input field + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @show: true to show the pass field, false to hide it + * Return 0 if OK, -ve on error + */ +int bc_ui_show_pass(struct udevice *dev, int seq, bool show); + +/** + * bc_ui_get_pass() - Get the pass entered by the user + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @passp: Returns pointer to the pass string + * Return 0 if OK, -ve on error + */ +int bc_ui_get_pass(struct udevice *dev, int seq, const char **passp); + +/** + * bc_ui_show_pass_msg() - Show or hide the pass message + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @show: true to show the message, false to hide it + * Return 0 if OK, -ve on error + */ +int bc_ui_show_pass_msg(struct udevice *dev, int seq, bool show); + +/** + * bc_ui_set_pass_msg() - Set the pass message text + * + * @dev: Display device + * @seq: Sequence number of the bootflow item + * @msg: Message text to display + * Return 0 if OK, -ve on error + */ +int bc_ui_set_pass_msg(struct udevice *dev, int seq, const char *msg); + #endif -- 2.43.0