1 #include <linux/acpi.h> 2 #include <acpi/acpi_drivers.h> 3 #include "tpm.h" 4 5 static const u8 tpm_ppi_uuid[] = { 6 0xA6, 0xFA, 0xDD, 0x3D, 7 0x1B, 0x36, 8 0xB4, 0x4E, 9 0xA4, 0x24, 10 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53 11 }; 12 static char *tpm_device_name = "TPM"; 13 14 #define TPM_PPI_REVISION_ID 1 15 #define TPM_PPI_FN_VERSION 1 16 #define TPM_PPI_FN_SUBREQ 2 17 #define TPM_PPI_FN_GETREQ 3 18 #define TPM_PPI_FN_GETACT 4 19 #define TPM_PPI_FN_GETRSP 5 20 #define TPM_PPI_FN_SUBREQ2 7 21 #define TPM_PPI_FN_GETOPR 8 22 #define PPI_TPM_REQ_MAX 22 23 #define PPI_VS_REQ_START 128 24 #define PPI_VS_REQ_END 255 25 #define PPI_VERSION_LEN 3 26 27 static acpi_status ppi_callback(acpi_handle handle, u32 level, void *context, 28 void **return_value) 29 { 30 acpi_status status; 31 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 32 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 33 if (strstr(buffer.pointer, context) != NULL) { 34 *return_value = handle; 35 kfree(buffer.pointer); 36 return AE_CTRL_TERMINATE; 37 } 38 return AE_OK; 39 } 40 41 static inline void ppi_assign_params(union acpi_object params[4], 42 u64 function_num) 43 { 44 params[0].type = ACPI_TYPE_BUFFER; 45 params[0].buffer.length = sizeof(tpm_ppi_uuid); 46 params[0].buffer.pointer = (char *)tpm_ppi_uuid; 47 params[1].type = ACPI_TYPE_INTEGER; 48 params[1].integer.value = TPM_PPI_REVISION_ID; 49 params[2].type = ACPI_TYPE_INTEGER; 50 params[2].integer.value = function_num; 51 params[3].type = ACPI_TYPE_PACKAGE; 52 params[3].package.count = 0; 53 params[3].package.elements = NULL; 54 } 55 56 static ssize_t tpm_show_ppi_version(struct device *dev, 57 struct device_attribute *attr, char *buf) 58 { 59 acpi_handle handle; 60 acpi_status status; 61 struct acpi_object_list input; 62 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 63 union acpi_object params[4]; 64 union acpi_object *obj; 65 66 input.count = 4; 67 ppi_assign_params(params, TPM_PPI_FN_VERSION); 68 input.pointer = params; 69 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 70 ACPI_UINT32_MAX, ppi_callback, NULL, 71 tpm_device_name, &handle); 72 if (ACPI_FAILURE(status)) 73 return -ENXIO; 74 75 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 76 ACPI_TYPE_STRING); 77 if (ACPI_FAILURE(status)) 78 return -ENOMEM; 79 obj = (union acpi_object *)output.pointer; 80 status = scnprintf(buf, PAGE_SIZE, "%s\n", obj->string.pointer); 81 kfree(output.pointer); 82 return status; 83 } 84 85 static ssize_t tpm_show_ppi_request(struct device *dev, 86 struct device_attribute *attr, char *buf) 87 { 88 acpi_handle handle; 89 acpi_status status; 90 struct acpi_object_list input; 91 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 92 union acpi_object params[4]; 93 union acpi_object *ret_obj; 94 95 input.count = 4; 96 ppi_assign_params(params, TPM_PPI_FN_GETREQ); 97 input.pointer = params; 98 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 99 ACPI_UINT32_MAX, ppi_callback, NULL, 100 tpm_device_name, &handle); 101 if (ACPI_FAILURE(status)) 102 return -ENXIO; 103 104 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 105 ACPI_TYPE_PACKAGE); 106 if (ACPI_FAILURE(status)) 107 return -ENOMEM; 108 /* 109 * output.pointer should be of package type, including two integers. 110 * The first is function return code, 0 means success and 1 means 111 * error. The second is pending TPM operation requested by the OS, 0 112 * means none and >0 means operation value. 113 */ 114 ret_obj = ((union acpi_object *)output.pointer)->package.elements; 115 if (ret_obj->type == ACPI_TYPE_INTEGER) { 116 if (ret_obj->integer.value) { 117 status = -EFAULT; 118 goto cleanup; 119 } 120 ret_obj++; 121 if (ret_obj->type == ACPI_TYPE_INTEGER) 122 status = scnprintf(buf, PAGE_SIZE, "%llu\n", 123 ret_obj->integer.value); 124 else 125 status = -EINVAL; 126 } else { 127 status = -EINVAL; 128 } 129 cleanup: 130 kfree(output.pointer); 131 return status; 132 } 133 134 static ssize_t tpm_store_ppi_request(struct device *dev, 135 struct device_attribute *attr, 136 const char *buf, size_t count) 137 { 138 char version[PPI_VERSION_LEN + 1]; 139 acpi_handle handle; 140 acpi_status status; 141 struct acpi_object_list input; 142 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 143 union acpi_object params[4]; 144 union acpi_object obj; 145 u32 req; 146 u64 ret; 147 148 input.count = 4; 149 ppi_assign_params(params, TPM_PPI_FN_VERSION); 150 input.pointer = params; 151 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 152 ACPI_UINT32_MAX, ppi_callback, NULL, 153 tpm_device_name, &handle); 154 if (ACPI_FAILURE(status)) 155 return -ENXIO; 156 157 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 158 ACPI_TYPE_STRING); 159 if (ACPI_FAILURE(status)) 160 return -ENOMEM; 161 strlcpy(version, 162 ((union acpi_object *)output.pointer)->string.pointer, 163 PPI_VERSION_LEN + 1); 164 kfree(output.pointer); 165 output.length = ACPI_ALLOCATE_BUFFER; 166 output.pointer = NULL; 167 /* 168 * the function to submit TPM operation request to pre-os environment 169 * is updated with function index from SUBREQ to SUBREQ2 since PPI 170 * version 1.1 171 */ 172 if (strcmp(version, "1.1") == -1) 173 params[2].integer.value = TPM_PPI_FN_SUBREQ; 174 else 175 params[2].integer.value = TPM_PPI_FN_SUBREQ2; 176 /* 177 * PPI spec defines params[3].type as ACPI_TYPE_PACKAGE. Some BIOS 178 * accept buffer/string/integer type, but some BIOS accept buffer/ 179 * string/package type. For PPI version 1.0 and 1.1, use buffer type 180 * for compatibility, and use package type since 1.2 according to spec. 181 */ 182 if (strcmp(version, "1.2") == -1) { 183 params[3].type = ACPI_TYPE_BUFFER; 184 params[3].buffer.length = sizeof(req); 185 sscanf(buf, "%d", &req); 186 params[3].buffer.pointer = (char *)&req; 187 } else { 188 params[3].package.count = 1; 189 obj.type = ACPI_TYPE_INTEGER; 190 sscanf(buf, "%llu", &obj.integer.value); 191 params[3].package.elements = &obj; 192 } 193 194 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 195 ACPI_TYPE_INTEGER); 196 if (ACPI_FAILURE(status)) 197 return -ENOMEM; 198 ret = ((union acpi_object *)output.pointer)->integer.value; 199 if (ret == 0) 200 status = (acpi_status)count; 201 else if (ret == 1) 202 status = -EPERM; 203 else 204 status = -EFAULT; 205 kfree(output.pointer); 206 return status; 207 } 208 209 static ssize_t tpm_show_ppi_transition_action(struct device *dev, 210 struct device_attribute *attr, 211 char *buf) 212 { 213 char version[PPI_VERSION_LEN + 1]; 214 acpi_handle handle; 215 acpi_status status; 216 struct acpi_object_list input; 217 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 218 union acpi_object params[4]; 219 u32 ret; 220 char *info[] = { 221 "None", 222 "Shutdown", 223 "Reboot", 224 "OS Vendor-specific", 225 "Error", 226 }; 227 input.count = 4; 228 ppi_assign_params(params, TPM_PPI_FN_VERSION); 229 input.pointer = params; 230 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 231 ACPI_UINT32_MAX, ppi_callback, NULL, 232 tpm_device_name, &handle); 233 if (ACPI_FAILURE(status)) 234 return -ENXIO; 235 236 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 237 ACPI_TYPE_STRING); 238 if (ACPI_FAILURE(status)) 239 return -ENOMEM; 240 strlcpy(version, 241 ((union acpi_object *)output.pointer)->string.pointer, 242 PPI_VERSION_LEN + 1); 243 /* 244 * PPI spec defines params[3].type as empty package, but some platforms 245 * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for 246 * compatibility, define params[3].type as buffer, if PPI version < 1.2 247 */ 248 if (strcmp(version, "1.2") == -1) { 249 params[3].type = ACPI_TYPE_BUFFER; 250 params[3].buffer.length = 0; 251 params[3].buffer.pointer = NULL; 252 } 253 params[2].integer.value = TPM_PPI_FN_GETACT; 254 kfree(output.pointer); 255 output.length = ACPI_ALLOCATE_BUFFER; 256 output.pointer = NULL; 257 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 258 ACPI_TYPE_INTEGER); 259 if (ACPI_FAILURE(status)) 260 return -ENOMEM; 261 ret = ((union acpi_object *)output.pointer)->integer.value; 262 if (ret < ARRAY_SIZE(info) - 1) 263 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]); 264 else 265 status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, 266 info[ARRAY_SIZE(info)-1]); 267 kfree(output.pointer); 268 return status; 269 } 270 271 static ssize_t tpm_show_ppi_response(struct device *dev, 272 struct device_attribute *attr, 273 char *buf) 274 { 275 acpi_handle handle; 276 acpi_status status; 277 struct acpi_object_list input; 278 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 279 union acpi_object params[4]; 280 union acpi_object *ret_obj; 281 u64 req; 282 283 input.count = 4; 284 ppi_assign_params(params, TPM_PPI_FN_GETRSP); 285 input.pointer = params; 286 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 287 ACPI_UINT32_MAX, ppi_callback, NULL, 288 tpm_device_name, &handle); 289 if (ACPI_FAILURE(status)) 290 return -ENXIO; 291 292 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 293 ACPI_TYPE_PACKAGE); 294 if (ACPI_FAILURE(status)) 295 return -ENOMEM; 296 /* 297 * parameter output.pointer should be of package type, including 298 * 3 integers. The first means function return code, the second means 299 * most recent TPM operation request, and the last means response to 300 * the most recent TPM operation request. Only if the first is 0, and 301 * the second integer is not 0, the response makes sense. 302 */ 303 ret_obj = ((union acpi_object *)output.pointer)->package.elements; 304 if (ret_obj->type != ACPI_TYPE_INTEGER) { 305 status = -EINVAL; 306 goto cleanup; 307 } 308 if (ret_obj->integer.value) { 309 status = -EFAULT; 310 goto cleanup; 311 } 312 ret_obj++; 313 if (ret_obj->type != ACPI_TYPE_INTEGER) { 314 status = -EINVAL; 315 goto cleanup; 316 } 317 if (ret_obj->integer.value) { 318 req = ret_obj->integer.value; 319 ret_obj++; 320 if (ret_obj->type != ACPI_TYPE_INTEGER) { 321 status = -EINVAL; 322 goto cleanup; 323 } 324 if (ret_obj->integer.value == 0) 325 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, 326 "0: Success"); 327 else if (ret_obj->integer.value == 0xFFFFFFF0) 328 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, 329 "0xFFFFFFF0: User Abort"); 330 else if (ret_obj->integer.value == 0xFFFFFFF1) 331 status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req, 332 "0xFFFFFFF1: BIOS Failure"); 333 else if (ret_obj->integer.value >= 1 && 334 ret_obj->integer.value <= 0x00000FFF) 335 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", 336 req, ret_obj->integer.value, 337 "Corresponding TPM error"); 338 else 339 status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n", 340 req, ret_obj->integer.value, 341 "Error"); 342 } else { 343 status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n", 344 ret_obj->integer.value, "No Recent Request"); 345 } 346 cleanup: 347 kfree(output.pointer); 348 return status; 349 } 350 351 static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) 352 { 353 char *str = buf; 354 char version[PPI_VERSION_LEN + 1]; 355 acpi_handle handle; 356 acpi_status status; 357 struct acpi_object_list input; 358 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 359 union acpi_object params[4]; 360 union acpi_object obj; 361 int i; 362 u32 ret; 363 char *info[] = { 364 "Not implemented", 365 "BIOS only", 366 "Blocked for OS by BIOS", 367 "User required", 368 "User not required", 369 }; 370 input.count = 4; 371 ppi_assign_params(params, TPM_PPI_FN_VERSION); 372 input.pointer = params; 373 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 374 ACPI_UINT32_MAX, ppi_callback, NULL, 375 tpm_device_name, &handle); 376 if (ACPI_FAILURE(status)) 377 return -ENXIO; 378 379 status = acpi_evaluate_object_typed(handle, "_DSM", &input, &output, 380 ACPI_TYPE_STRING); 381 if (ACPI_FAILURE(status)) 382 return -ENOMEM; 383 384 strlcpy(version, 385 ((union acpi_object *)output.pointer)->string.pointer, 386 PPI_VERSION_LEN + 1); 387 kfree(output.pointer); 388 output.length = ACPI_ALLOCATE_BUFFER; 389 output.pointer = NULL; 390 if (strcmp(version, "1.2") == -1) 391 return -EPERM; 392 393 params[2].integer.value = TPM_PPI_FN_GETOPR; 394 params[3].package.count = 1; 395 obj.type = ACPI_TYPE_INTEGER; 396 params[3].package.elements = &obj; 397 for (i = start; i <= end; i++) { 398 obj.integer.value = i; 399 status = acpi_evaluate_object_typed(handle, "_DSM", 400 &input, &output, ACPI_TYPE_INTEGER); 401 if (ACPI_FAILURE(status)) 402 return -ENOMEM; 403 404 ret = ((union acpi_object *)output.pointer)->integer.value; 405 if (ret > 0 && ret < ARRAY_SIZE(info)) 406 str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n", 407 i, ret, info[ret]); 408 kfree(output.pointer); 409 output.length = ACPI_ALLOCATE_BUFFER; 410 output.pointer = NULL; 411 } 412 return str - buf; 413 } 414 415 static ssize_t tpm_show_ppi_tcg_operations(struct device *dev, 416 struct device_attribute *attr, 417 char *buf) 418 { 419 return show_ppi_operations(buf, 0, PPI_TPM_REQ_MAX); 420 } 421 422 static ssize_t tpm_show_ppi_vs_operations(struct device *dev, 423 struct device_attribute *attr, 424 char *buf) 425 { 426 return show_ppi_operations(buf, PPI_VS_REQ_START, PPI_VS_REQ_END); 427 } 428 429 static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL); 430 static DEVICE_ATTR(request, S_IRUGO | S_IWUSR | S_IWGRP, 431 tpm_show_ppi_request, tpm_store_ppi_request); 432 static DEVICE_ATTR(transition_action, S_IRUGO, 433 tpm_show_ppi_transition_action, NULL); 434 static DEVICE_ATTR(response, S_IRUGO, tpm_show_ppi_response, NULL); 435 static DEVICE_ATTR(tcg_operations, S_IRUGO, tpm_show_ppi_tcg_operations, NULL); 436 static DEVICE_ATTR(vs_operations, S_IRUGO, tpm_show_ppi_vs_operations, NULL); 437 438 static struct attribute *ppi_attrs[] = { 439 &dev_attr_version.attr, 440 &dev_attr_request.attr, 441 &dev_attr_transition_action.attr, 442 &dev_attr_response.attr, 443 &dev_attr_tcg_operations.attr, 444 &dev_attr_vs_operations.attr, NULL, 445 }; 446 static struct attribute_group ppi_attr_grp = { 447 .name = "ppi", 448 .attrs = ppi_attrs 449 }; 450 451 int tpm_add_ppi(struct kobject *parent) 452 { 453 return sysfs_create_group(parent, &ppi_attr_grp); 454 } 455 456 void tpm_remove_ppi(struct kobject *parent) 457 { 458 sysfs_remove_group(parent, &ppi_attr_grp); 459 } 460