/** * @file sdrv_crypto_mailbox_basic_mgmt.c * @brief Semidrive CRYPTO mailbox basic source file. * * @copyright Copyright (c) 2021 Semidrive Semiconductor. * All rights reserved. */ #include #define CMD_BASIC_GET_DEVICE_INFO_LEN 32 /** * @brief get device info. * * This function get ehsm device info. * * @param[in] key_id internel key id, use for encrypt device info. * @param[in] mac_buf for auth. * @param[out] device_info_buff out buff. * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_get_device_info(uint16_t key_id, uint32_t *device_info_buf, uint8_t *mac_buf) { uint32_t cmd_buf[8] = {0}; cmd_get_device_info_t *cmd_get_device_info = NULL; uint32_t ret; cmd_get_device_info = (cmd_get_device_info_t *)cmd_buf; cmd_get_device_info->cmd_id = GET_DEVICE_INFO; cmd_get_device_info->info_len = CMD_BASIC_GET_DEVICE_INFO_LEN; set_big_endian_2byte((uint8_t *)cmd_get_device_info->key_id, key_id); set_big_endian_4byte((uint8_t *)cmd_get_device_info->device_info_ptr, (uint32_t)device_info_buf); set_big_endian_4byte((uint8_t *)cmd_get_device_info->aut_info_ptr, (uint32_t)mac_buf); get_otp_key_aut_mac(&key_id, 1, (uint8_t *)cmd_buf, mac_buf); ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { print_buf_U8((uint8_t *)device_info_buf, 32, "device_info_buf"); } else { printf(" get device info failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; } /** * @brief get device status. * * This function get ehsm device status. * * @param[in] key_id internel key id, use for encrypt device status. * @param[in] mac_buf for auth. * @param[out] device_status_buff out buff. * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_get_device_status(uint16_t key_id, uint32_t *device_status_buf, uint8_t *mac_buf) { uint32_t cmd_buf[8] = {0}; cmd_get_device_status_t *cmd_get_device_status = NULL; uint32_t ret; cmd_get_device_status = (cmd_get_device_status_t *)cmd_buf; cmd_get_device_status->cmd_id = GET_DEVICE_STATUS; cmd_get_device_status->status_len = 16; set_big_endian_2byte((uint8_t *)cmd_get_device_status->key_id, key_id); set_big_endian_4byte((uint8_t *)cmd_get_device_status->device_status_ptr, (uint32_t)device_status_buf); set_big_endian_4byte((uint8_t *)cmd_get_device_status->aut_info_ptr, (uint32_t)mac_buf); get_otp_key_aut_mac(&key_id, 1, (uint8_t *)cmd_buf, mac_buf); ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { print_buf_U8((uint8_t *)device_status_buf, 16, "device_status_buf"); } else { printf(" get device status failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; } /** * @brief get 256bit random key. * * This function get 256bit random key use for ske or hmac, key_id must != 0. * * @param[in] key_id internel key id, use for encrypt random key. * @param[in] mac_buf for auth. * @param[out] key out buff. * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_get_ske_hmac_256bit_key(uint16_t key_id, uint32_t *key, uint8_t *mac_buf) { uint32_t cmd_buf[8] = {0}; uint32_t ret; cmd_generate_key_t *cmd_get_key = NULL; cmd_get_key = (cmd_generate_key_t *)cmd_buf; cmd_get_key->cmd_id = GENERATE_KEY; cmd_get_key->key_bytes = 32; set_big_endian_2byte((uint8_t *)cmd_get_key->key_id, key_id); set_big_endian_4byte((uint8_t *)cmd_get_key->key_ptr, (uint32_t)key); set_big_endian_4byte((uint8_t *)cmd_get_key->aut_info_ptr, (uint32_t)mac_buf); get_otp_key_aut_mac(&key_id, 1, (uint8_t *)cmd_buf, mac_buf); ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { printf(" get random key success \n"); print_buf_U8((uint8_t *)key, 32, "key"); } else { printf(" get random key failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; } /** * @brief self destroy. * * This function can destroy SSRK, this cmd only work when seip on high secure * status. * * @param[in] mac_buf for auth. * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_key_self_destroy(uint8_t *mac_buf) { uint32_t cmd_buf[8] = {0}; uint32_t ret; cmd_self_destroy_t *cmd_destroy = NULL; cmd_destroy = (cmd_self_destroy_t *)cmd_buf; cmd_destroy->cmd_id = SELF_DESTROY; set_big_endian_4byte((uint8_t *)cmd_destroy->aut_info_ptr, (uint32_t)mac_buf); ret = cmd_get_cmac(CMAC_SKE_ALG_SM4, CMD_KEY_INTERNAL, 1, (uint8_t *)cmd_buf, 32, mac_buf, 16); if (CMD_RETURN_SUCCESS != ret) { return CMD_SEIP_ERROR; } else { ; } ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { printf(" SEIP destroy success\n"); } else { printf(" SEIP destroy failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; } /** * @brief jump to addr run * * This function can set seip run addr, after set seip will jump to run * * @param[in] addr addr for seip run start * @param[in] mac_buf for auth * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_jump(uint32_t addr, uint8_t *mac_buf) { uint16_t key_id = 1; uint32_t cmd_buf[8] = {0}; uint32_t ret; cmd_seip_jump_t *cmd_jump = NULL; cmd_jump = (cmd_seip_jump_t *)cmd_buf; cmd_jump->cmd_id = SEIP_JUMP; set_big_endian_2byte((uint8_t *)cmd_jump->key_id, key_id); set_big_endian_4byte((uint8_t *)cmd_jump->addr_ptr, (uint32_t)addr); set_big_endian_4byte((uint8_t *)cmd_jump->aut_info_ptr, (uint32_t)mac_buf); ret = cmd_get_cmac(CMAC_SKE_ALG_SM4, CMD_KEY_INTERNAL, 1, (uint8_t *)cmd_buf, 32, mac_buf, 16); if (CMD_RETURN_SUCCESS != ret) { return CMD_SEIP_ERROR; } else { ; } ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { printf(" SEIP jump success\n"); } else { printf(" SEIP jump failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; } /** * @brief disable seip * * This function disable seip, pincode used for auth * * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_disable_seip(void) { uint32_t cmd_buf[8] = {0}; uint32_t ret; cmd_seip_disable_t *cmd_disable = NULL; const uint8_t pin_code[] = { 0x32, 0x74, 0xDD, 0x6C, 0xD3, 0x26, 0xD7, 0x23, 0x65, 0xD8, 0xF8, 0x67, 0x92, 0xE7, 0x16, 0xE4, }; cmd_disable = (cmd_seip_disable_t *)cmd_buf; cmd_disable->cmd_id = SEIP_DISABLE; memcpy_(cmd_disable->pin_code, (void *)pin_code, 16); ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { printf(" SEIP disable success\n"); } else { printf(" SEIP disable failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; } /** * @brief set sensor clk * * This function config sensor clk, for protect seip * * @param[in] reg_addr sensor clk reg addr * @param[in] reg_value value * @param[in] reg_max_value max value * @param[in] reg_min_value min value * @return CMD_RETURN_SUCCESS or error code. */ sdrv_crypto_error_status_e cmd_sensor_clk_cfg(uint32_t reg_addr, uint32_t reg_value, uint32_t reg_max_value, uint32_t reg_min_value) { uint32_t cmd_buf[8] = {0}; uint32_t ret; cmd_sensor_clk_cfg_t *cmd_sensor_cfg = NULL; cmd_sensor_cfg = (cmd_sensor_clk_cfg_t *)cmd_buf; cmd_sensor_cfg->cmd_id = SENSOR_CLK_CFG; set_big_endian_4byte((uint8_t *)cmd_sensor_cfg->reg_addr, (uint32_t)reg_addr); set_big_endian_4byte((uint8_t *)cmd_sensor_cfg->reg_value, (uint32_t)reg_value); set_big_endian_4byte((uint8_t *)cmd_sensor_cfg->reg_max_value, (uint32_t)reg_max_value); set_big_endian_4byte((uint8_t *)cmd_sensor_cfg->reg_min_value, (uint32_t)reg_min_value); ret = send_cmd_and_wait_response((uint32_t *)cmd_buf); if (SEIP_SUCCESS == ret) { printf(" sensor_clk_cfg success\n"); } else { printf(" sensor_clk_cfg failure, ret=%x\n", ret); return CMD_RETURN_FAIL; } return CMD_RETURN_SUCCESS; }