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