From 294a5971c94099277ee5b5589c060896cf22c495 Mon Sep 17 00:00:00 2001 From: Richard Marian Thomaiyar Date: Thu, 20 Jun 2019 15:26:50 +0530 Subject: [PATCH] Support Get/Set Security mode command Support added for get/set security mode oem command. This command is used to read / write the RestrictionMode property which is saved in U-Boot environment variable. U-Boot command provides a way to downgrade RestrictionMode property value, which is not allowed in normal mode from Host interface Tested: 1. Verified get security mode returns proper value read from U-Boot environment variable. cmdtool.efi 20 C0 B3 2. Verified set security mode updates U-Boot environment variable and it is reflected in linux too cmdtool.efi 20 C0 B4 4 3. Verified negative test cases with improper values and it throws correct errors Signed-off-by: Richard Marian Thomaiyar --- board/aspeed/ast-g5/ipmi-handler.c | 63 +++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/board/aspeed/ast-g5/ipmi-handler.c b/board/aspeed/ast-g5/ipmi-handler.c index 5e78546..4e921bd 100644 --- a/board/aspeed/ast-g5/ipmi-handler.c +++ b/board/aspeed/ast-g5/ipmi-handler.c @@ -20,10 +20,19 @@ #define CMD_FWUPD_SET_OPTIONS 0x2B #define CMD_FWUPD_IMAGE_WRITE 0x2C #define CMD_INTL_OEM_GET_BUFFER_SIZE 0x66 +#define CMD_INTL_OEM_GET_SEC_MODE 0xB3 +#define CMD_INTL_OEM_SET_SEC_MODE 0xB4 #define MAX_KCS_BUF_SIZE 1020 /* (0xFF * 4) */ #define MAX_IPMB_BUF_SIZE 1020 /* (0xFF * 4) */ +/* Restriction mode values */ +#define RESTRICTION_MODE_MIN_VALUE 3 /*Provisioning*/ +#define RESTRICION_MODE_MAX_VALUE 5 /*Provisioned host disabled */ + +#define STR_ENV_PROVISION "provision" + + typedef u16 (*fun_handler)(u8 *req, u16 req_len, u8 *res); struct ipmi_cmd_table { @@ -53,6 +62,11 @@ struct intc_get_buf_size_res { u8 kcs_size; u8 ipmb_size; }; +struct intc_get_secuirty_mode_res { + u8 completion_code; + u8 restriction_mode; + u8 special_mode; +}; static u16 get_device_id(u8 *req, u16 req_len, u8 *res) { @@ -120,6 +134,51 @@ static u16 intel_get_buffer_size(u8 *req, u16 req_len, u8 *res) return sizeof(struct intc_get_buf_size_res); } +static u16 intel_get_security_mode(u8 *req, u16 req_len, u8 *res) +{ + char *cmdline = NULL; + struct intc_get_secuirty_mode_res *result = + (struct intc_get_secuirty_mode_res *)res; + + if (req_len != 0) { + result->completion_code = IPMI_CC_INVALID_DATA_LENGTH; + return sizeof(result->completion_code); + } + + cmdline = getenv(STR_ENV_PROVISION); + if (!cmdline) { + /* Default provision must be set only by linux */ + result->completion_code = IPMI_CC_UNSPECIFIED; + return sizeof(result->completion_code); + } + result->restriction_mode = simple_strtol(cmdline, NULL, 10); + /* special mode is non-volatile and not applicable in U-Boot */ + result->special_mode = 0; + result->completion_code = IPMI_CC_OK; + + return sizeof(*result); +} + +static u16 intel_set_security_mode(u8 *req, u16 req_len, u8 *res) +{ + if (req_len != sizeof(*req)) { + *res = IPMI_CC_INVALID_DATA_LENGTH; + return sizeof(*res); + } + + if (*req > RESTRICION_MODE_MAX_VALUE || + *req < RESTRICTION_MODE_MIN_VALUE) { + *res = IPMI_CC_INVALID_DATA_FIELD; + return sizeof(*res); + } + + setenv_ulong(STR_ENV_PROVISION, *req); + saveenv(); + *res = IPMI_CC_OK; + + return sizeof(*res); +} + const struct ipmi_cmd_table cmd_info[] = { { NETFN_APP, CMD_APP_GET_DEV_ID, get_device_id }, { NETFN_APP, CMD_APP_GET_SELF_TEST_RESULTS, get_self_test_result }, @@ -131,7 +190,9 @@ const struct ipmi_cmd_table cmd_info[] = { { NETFN_FIRMWARE, CMD_FWUPD_GET_UPDATE_STATUS, fwupd_get_update_status }, { NETFN_FIRMWARE, CMD_FWUPD_SET_OPTIONS, fwupd_set_options }, { NETFN_FIRMWARE, CMD_FWUPD_IMAGE_WRITE, fwupd_image_write }, - { NETFN_INTEL_OEM, CMD_INTL_OEM_GET_BUFFER_SIZE, intel_get_buffer_size } + { NETFN_INTEL_OEM, CMD_INTL_OEM_GET_BUFFER_SIZE, intel_get_buffer_size }, + { NETFN_INTEL_OEM, CMD_INTL_OEM_GET_SEC_MODE, intel_get_security_mode }, + { NETFN_INTEL_OEM, CMD_INTL_OEM_SET_SEC_MODE, intel_set_security_mode }, }; #define CMD_TABLE_SIZE ARRAY_SIZE(cmd_info)