Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: btintel: Add support for hybrid signature for ScP2 onwards

If FW image has hybrid signature (ECDSA and LMS) then send CSS header,
ECDSA public key, ECDSA signature, LMS public key, LMS signature and
command buffer to device.

Signed-off-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Kiran K and committed by
Luiz Augusto von Dentz
21b51648 728a3d12

+72 -8
+72 -8
drivers/bluetooth/btintel.c
··· 35 35 DSM_SET_RESET_METHOD = 3, 36 36 }; 37 37 38 + /* Hybrid ECDSA + LMS */ 39 + #define BTINTEL_RSA_HEADER_VER 0x00010000 40 + #define BTINTEL_ECDSA_HEADER_VER 0x00020000 41 + #define BTINTEL_HYBRID_HEADER_VER 0x00069700 42 + #define BTINTEL_ECDSA_OFFSET 128 43 + #define BTINTEL_CSS_HEADER_SIZE 128 44 + #define BTINTEL_ECDSA_PUB_KEY_SIZE 96 45 + #define BTINTEL_ECDSA_SIG_SIZE 96 46 + #define BTINTEL_LMS_OFFSET 320 47 + #define BTINTEL_LMS_PUB_KEY_SIZE 52 48 + #define BTINTEL_LMS_SIG_SIZE 1744 49 + #define BTINTEL_CMD_BUFFER_OFFSET 2116 50 + 38 51 #define BTINTEL_BT_DOMAIN 0x12 39 52 #define BTINTEL_SAR_LEGACY 0 40 53 #define BTINTEL_SAR_INC_PWR 1 ··· 523 510 return -EINVAL; 524 511 } 525 512 526 - /* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */ 527 - if (version->sbe_type > 0x01) { 513 + /* Secure boot engine type can be 0 (RSA), 1 (ECDSA), 2 (LMS), 3 (ECDSA + LMS) */ 514 + if (version->sbe_type > 0x03) { 528 515 bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)", 529 516 version->sbe_type); 530 517 return -EINVAL; ··· 1043 1030 return 0; 1044 1031 } 1045 1032 1033 + static int btintel_sfi_hybrid_header_secure_send(struct hci_dev *hdev, 1034 + const struct firmware *fw) 1035 + { 1036 + int err; 1037 + 1038 + err = btintel_secure_send(hdev, 0x00, BTINTEL_CSS_HEADER_SIZE, fw->data); 1039 + if (err < 0) { 1040 + bt_dev_err(hdev, "Failed to send firmware CSS header (%d)", err); 1041 + return err; 1042 + } 1043 + 1044 + err = btintel_secure_send(hdev, 0x03, BTINTEL_ECDSA_PUB_KEY_SIZE, 1045 + fw->data + BTINTEL_ECDSA_OFFSET); 1046 + if (err < 0) { 1047 + bt_dev_err(hdev, "Failed to send firmware ECDSA pkey (%d)", err); 1048 + return err; 1049 + } 1050 + 1051 + err = btintel_secure_send(hdev, 0x02, BTINTEL_ECDSA_SIG_SIZE, 1052 + fw->data + BTINTEL_ECDSA_OFFSET + BTINTEL_ECDSA_PUB_KEY_SIZE); 1053 + if (err < 0) { 1054 + bt_dev_err(hdev, "Failed to send firmware ECDSA signature (%d)", err); 1055 + return err; 1056 + } 1057 + 1058 + err = btintel_secure_send(hdev, 0x05, BTINTEL_LMS_PUB_KEY_SIZE, 1059 + fw->data + BTINTEL_LMS_OFFSET); 1060 + if (err < 0) { 1061 + bt_dev_err(hdev, "Failed to send firmware LMS pkey (%d)", err); 1062 + return err; 1063 + } 1064 + 1065 + err = btintel_secure_send(hdev, 0x04, BTINTEL_LMS_SIG_SIZE, 1066 + fw->data + BTINTEL_LMS_OFFSET + BTINTEL_LMS_PUB_KEY_SIZE); 1067 + if (err < 0) { 1068 + bt_dev_err(hdev, "Failed to send firmware LMS signature (%d)", err); 1069 + return err; 1070 + } 1071 + 1072 + return 0; 1073 + } 1074 + 1046 1075 static int btintel_download_firmware_payload(struct hci_dev *hdev, 1047 1076 const struct firmware *fw, 1048 1077 size_t offset) ··· 1258 1203 * Command Buffer. 1259 1204 * 1260 1205 * CSS Header byte positions 0x08 to 0x0B represent the CSS Header 1261 - * version: RSA(0x00010000) , ECDSA (0x00020000) 1206 + * version: RSA(0x00010000) , ECDSA (0x00020000) , HYBRID (0x00069700) 1262 1207 */ 1263 1208 css_header_ver = get_unaligned_le32(fw->data + CSS_HEADER_OFFSET); 1264 - if (css_header_ver != 0x00010000) { 1265 - bt_dev_err(hdev, "Invalid CSS Header version"); 1209 + if (css_header_ver != BTINTEL_RSA_HEADER_VER && 1210 + css_header_ver != BTINTEL_HYBRID_HEADER_VER) { 1211 + bt_dev_err(hdev, "Invalid CSS Header version: 0x%8.8x", css_header_ver); 1266 1212 return -EINVAL; 1267 1213 } 1268 1214 ··· 1281 1225 err = btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN); 1282 1226 if (err) 1283 1227 return err; 1284 - } else if (hw_variant >= 0x17) { 1228 + } else if (hw_variant >= 0x17 && css_header_ver == BTINTEL_RSA_HEADER_VER) { 1285 1229 /* Check if CSS header for ECDSA follows the RSA header */ 1286 1230 if (fw->data[ECDSA_OFFSET] != 0x06) 1287 1231 return -EINVAL; 1288 1232 1289 1233 /* Check if the CSS Header version is ECDSA(0x00020000) */ 1290 1234 css_header_ver = get_unaligned_le32(fw->data + ECDSA_OFFSET + CSS_HEADER_OFFSET); 1291 - if (css_header_ver != 0x00020000) { 1292 - bt_dev_err(hdev, "Invalid CSS Header version"); 1235 + if (css_header_ver != BTINTEL_ECDSA_HEADER_VER) { 1236 + bt_dev_err(hdev, "Invalid CSS Header version: 0x%8.8x", css_header_ver); 1293 1237 return -EINVAL; 1294 1238 } 1295 1239 ··· 1312 1256 if (err) 1313 1257 return err; 1314 1258 } 1259 + } else if (hw_variant >= 0x20 && css_header_ver == BTINTEL_HYBRID_HEADER_VER) { 1260 + err = btintel_sfi_hybrid_header_secure_send(hdev, fw); 1261 + if (err) 1262 + return err; 1263 + 1264 + err = btintel_download_firmware_payload(hdev, fw, BTINTEL_CMD_BUFFER_OFFSET); 1265 + if (err) 1266 + return err; 1315 1267 } 1316 1268 return 0; 1317 1269 }