15d0682beSSumit Garg // SPDX-License-Identifier: GPL-2.0-only 25d0682beSSumit Garg /* 35d0682beSSumit Garg * Copyright (C) 2010 IBM Corporation 45d0682beSSumit Garg * Copyright (c) 2019-2021, Linaro Limited 55d0682beSSumit Garg * 65d0682beSSumit Garg * See Documentation/security/keys/trusted-encrypted.rst 75d0682beSSumit Garg */ 85d0682beSSumit Garg 95d0682beSSumit Garg #include <keys/user-type.h> 105d0682beSSumit Garg #include <keys/trusted-type.h> 110a95ebc9SSumit Garg #include <keys/trusted_tee.h> 125d0682beSSumit Garg #include <keys/trusted_tpm.h> 135d0682beSSumit Garg #include <linux/capability.h> 145d0682beSSumit Garg #include <linux/err.h> 155d0682beSSumit Garg #include <linux/init.h> 165d0682beSSumit Garg #include <linux/key-type.h> 175d0682beSSumit Garg #include <linux/module.h> 185d0682beSSumit Garg #include <linux/parser.h> 195d0682beSSumit Garg #include <linux/rcupdate.h> 205d0682beSSumit Garg #include <linux/slab.h> 215d0682beSSumit Garg #include <linux/static_call.h> 225d0682beSSumit Garg #include <linux/string.h> 235d0682beSSumit Garg #include <linux/uaccess.h> 245d0682beSSumit Garg 255d0682beSSumit Garg static char *trusted_key_source; 265d0682beSSumit Garg module_param_named(source, trusted_key_source, charp, 0); 275d0682beSSumit Garg MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)"); 285d0682beSSumit Garg 295d0682beSSumit Garg static const struct trusted_key_source trusted_key_sources[] = { 305d0682beSSumit Garg #if defined(CONFIG_TCG_TPM) 315d0682beSSumit Garg { "tpm", &trusted_key_tpm_ops }, 325d0682beSSumit Garg #endif 330a95ebc9SSumit Garg #if defined(CONFIG_TEE) 340a95ebc9SSumit Garg { "tee", &trusted_key_tee_ops }, 350a95ebc9SSumit Garg #endif 365d0682beSSumit Garg }; 375d0682beSSumit Garg 385d0682beSSumit Garg DEFINE_STATIC_CALL_NULL(trusted_key_init, *trusted_key_sources[0].ops->init); 395d0682beSSumit Garg DEFINE_STATIC_CALL_NULL(trusted_key_seal, *trusted_key_sources[0].ops->seal); 405d0682beSSumit Garg DEFINE_STATIC_CALL_NULL(trusted_key_unseal, 415d0682beSSumit Garg *trusted_key_sources[0].ops->unseal); 425d0682beSSumit Garg DEFINE_STATIC_CALL_NULL(trusted_key_get_random, 435d0682beSSumit Garg *trusted_key_sources[0].ops->get_random); 445d0682beSSumit Garg DEFINE_STATIC_CALL_NULL(trusted_key_exit, *trusted_key_sources[0].ops->exit); 455d0682beSSumit Garg static unsigned char migratable; 465d0682beSSumit Garg 475d0682beSSumit Garg enum { 485d0682beSSumit Garg Opt_err, 495d0682beSSumit Garg Opt_new, Opt_load, Opt_update, 505d0682beSSumit Garg }; 515d0682beSSumit Garg 525d0682beSSumit Garg static const match_table_t key_tokens = { 535d0682beSSumit Garg {Opt_new, "new"}, 545d0682beSSumit Garg {Opt_load, "load"}, 555d0682beSSumit Garg {Opt_update, "update"}, 565d0682beSSumit Garg {Opt_err, NULL} 575d0682beSSumit Garg }; 585d0682beSSumit Garg 595d0682beSSumit Garg /* 605d0682beSSumit Garg * datablob_parse - parse the keyctl data and fill in the 615d0682beSSumit Garg * payload structure 625d0682beSSumit Garg * 635d0682beSSumit Garg * On success returns 0, otherwise -EINVAL. 645d0682beSSumit Garg */ 65*60dc5f1bSJames Bottomley static int datablob_parse(char **datablob, struct trusted_key_payload *p) 665d0682beSSumit Garg { 675d0682beSSumit Garg substring_t args[MAX_OPT_ARGS]; 685d0682beSSumit Garg long keylen; 695d0682beSSumit Garg int ret = -EINVAL; 705d0682beSSumit Garg int key_cmd; 715d0682beSSumit Garg char *c; 725d0682beSSumit Garg 735d0682beSSumit Garg /* main command */ 74*60dc5f1bSJames Bottomley c = strsep(datablob, " \t"); 755d0682beSSumit Garg if (!c) 765d0682beSSumit Garg return -EINVAL; 775d0682beSSumit Garg key_cmd = match_token(c, key_tokens, args); 785d0682beSSumit Garg switch (key_cmd) { 795d0682beSSumit Garg case Opt_new: 805d0682beSSumit Garg /* first argument is key size */ 81*60dc5f1bSJames Bottomley c = strsep(datablob, " \t"); 825d0682beSSumit Garg if (!c) 835d0682beSSumit Garg return -EINVAL; 845d0682beSSumit Garg ret = kstrtol(c, 10, &keylen); 855d0682beSSumit Garg if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE) 865d0682beSSumit Garg return -EINVAL; 875d0682beSSumit Garg p->key_len = keylen; 885d0682beSSumit Garg ret = Opt_new; 895d0682beSSumit Garg break; 905d0682beSSumit Garg case Opt_load: 915d0682beSSumit Garg /* first argument is sealed blob */ 92*60dc5f1bSJames Bottomley c = strsep(datablob, " \t"); 935d0682beSSumit Garg if (!c) 945d0682beSSumit Garg return -EINVAL; 955d0682beSSumit Garg p->blob_len = strlen(c) / 2; 965d0682beSSumit Garg if (p->blob_len > MAX_BLOB_SIZE) 975d0682beSSumit Garg return -EINVAL; 985d0682beSSumit Garg ret = hex2bin(p->blob, c, p->blob_len); 995d0682beSSumit Garg if (ret < 0) 1005d0682beSSumit Garg return -EINVAL; 1015d0682beSSumit Garg ret = Opt_load; 1025d0682beSSumit Garg break; 1035d0682beSSumit Garg case Opt_update: 1045d0682beSSumit Garg ret = Opt_update; 1055d0682beSSumit Garg break; 1065d0682beSSumit Garg case Opt_err: 1075d0682beSSumit Garg return -EINVAL; 1085d0682beSSumit Garg } 1095d0682beSSumit Garg return ret; 1105d0682beSSumit Garg } 1115d0682beSSumit Garg 1125d0682beSSumit Garg static struct trusted_key_payload *trusted_payload_alloc(struct key *key) 1135d0682beSSumit Garg { 1145d0682beSSumit Garg struct trusted_key_payload *p = NULL; 1155d0682beSSumit Garg int ret; 1165d0682beSSumit Garg 1175d0682beSSumit Garg ret = key_payload_reserve(key, sizeof(*p)); 1185d0682beSSumit Garg if (ret < 0) 119aec00aa0SColin Ian King goto err; 1205d0682beSSumit Garg p = kzalloc(sizeof(*p), GFP_KERNEL); 121aec00aa0SColin Ian King if (!p) 122aec00aa0SColin Ian King goto err; 1235d0682beSSumit Garg 1245d0682beSSumit Garg p->migratable = migratable; 125aec00aa0SColin Ian King err: 1265d0682beSSumit Garg return p; 1275d0682beSSumit Garg } 1285d0682beSSumit Garg 1295d0682beSSumit Garg /* 1305d0682beSSumit Garg * trusted_instantiate - create a new trusted key 1315d0682beSSumit Garg * 1325d0682beSSumit Garg * Unseal an existing trusted blob or, for a new key, get a 1335d0682beSSumit Garg * random key, then seal and create a trusted key-type key, 1345d0682beSSumit Garg * adding it to the specified keyring. 1355d0682beSSumit Garg * 1365d0682beSSumit Garg * On success, return 0. Otherwise return errno. 1375d0682beSSumit Garg */ 1385d0682beSSumit Garg static int trusted_instantiate(struct key *key, 1395d0682beSSumit Garg struct key_preparsed_payload *prep) 1405d0682beSSumit Garg { 1415d0682beSSumit Garg struct trusted_key_payload *payload = NULL; 1425d0682beSSumit Garg size_t datalen = prep->datalen; 143*60dc5f1bSJames Bottomley char *datablob, *orig_datablob; 1445d0682beSSumit Garg int ret = 0; 1455d0682beSSumit Garg int key_cmd; 1465d0682beSSumit Garg size_t key_len; 1475d0682beSSumit Garg 1485d0682beSSumit Garg if (datalen <= 0 || datalen > 32767 || !prep->data) 1495d0682beSSumit Garg return -EINVAL; 1505d0682beSSumit Garg 151*60dc5f1bSJames Bottomley orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL); 1525d0682beSSumit Garg if (!datablob) 1535d0682beSSumit Garg return -ENOMEM; 1545d0682beSSumit Garg memcpy(datablob, prep->data, datalen); 1555d0682beSSumit Garg datablob[datalen] = '\0'; 1565d0682beSSumit Garg 1575d0682beSSumit Garg payload = trusted_payload_alloc(key); 1585d0682beSSumit Garg if (!payload) { 1595d0682beSSumit Garg ret = -ENOMEM; 1605d0682beSSumit Garg goto out; 1615d0682beSSumit Garg } 1625d0682beSSumit Garg 163*60dc5f1bSJames Bottomley key_cmd = datablob_parse(&datablob, payload); 1645d0682beSSumit Garg if (key_cmd < 0) { 1655d0682beSSumit Garg ret = key_cmd; 1665d0682beSSumit Garg goto out; 1675d0682beSSumit Garg } 1685d0682beSSumit Garg 1695d0682beSSumit Garg dump_payload(payload); 1705d0682beSSumit Garg 1715d0682beSSumit Garg switch (key_cmd) { 1725d0682beSSumit Garg case Opt_load: 1735d0682beSSumit Garg ret = static_call(trusted_key_unseal)(payload, datablob); 1745d0682beSSumit Garg dump_payload(payload); 1755d0682beSSumit Garg if (ret < 0) 1765d0682beSSumit Garg pr_info("key_unseal failed (%d)\n", ret); 1775d0682beSSumit Garg break; 1785d0682beSSumit Garg case Opt_new: 1795d0682beSSumit Garg key_len = payload->key_len; 1805d0682beSSumit Garg ret = static_call(trusted_key_get_random)(payload->key, 1815d0682beSSumit Garg key_len); 1825d0682beSSumit Garg if (ret < 0) 1835d0682beSSumit Garg goto out; 1845d0682beSSumit Garg 1855d0682beSSumit Garg if (ret != key_len) { 1865d0682beSSumit Garg pr_info("key_create failed (%d)\n", ret); 1875d0682beSSumit Garg ret = -EIO; 1885d0682beSSumit Garg goto out; 1895d0682beSSumit Garg } 1905d0682beSSumit Garg 1915d0682beSSumit Garg ret = static_call(trusted_key_seal)(payload, datablob); 1925d0682beSSumit Garg if (ret < 0) 1935d0682beSSumit Garg pr_info("key_seal failed (%d)\n", ret); 1945d0682beSSumit Garg break; 1955d0682beSSumit Garg default: 1965d0682beSSumit Garg ret = -EINVAL; 1975d0682beSSumit Garg } 1985d0682beSSumit Garg out: 199*60dc5f1bSJames Bottomley kfree_sensitive(orig_datablob); 2005d0682beSSumit Garg if (!ret) 2015d0682beSSumit Garg rcu_assign_keypointer(key, payload); 2025d0682beSSumit Garg else 2035d0682beSSumit Garg kfree_sensitive(payload); 2045d0682beSSumit Garg return ret; 2055d0682beSSumit Garg } 2065d0682beSSumit Garg 2075d0682beSSumit Garg static void trusted_rcu_free(struct rcu_head *rcu) 2085d0682beSSumit Garg { 2095d0682beSSumit Garg struct trusted_key_payload *p; 2105d0682beSSumit Garg 2115d0682beSSumit Garg p = container_of(rcu, struct trusted_key_payload, rcu); 2125d0682beSSumit Garg kfree_sensitive(p); 2135d0682beSSumit Garg } 2145d0682beSSumit Garg 2155d0682beSSumit Garg /* 2165d0682beSSumit Garg * trusted_update - reseal an existing key with new PCR values 2175d0682beSSumit Garg */ 2185d0682beSSumit Garg static int trusted_update(struct key *key, struct key_preparsed_payload *prep) 2195d0682beSSumit Garg { 2205d0682beSSumit Garg struct trusted_key_payload *p; 2215d0682beSSumit Garg struct trusted_key_payload *new_p; 2225d0682beSSumit Garg size_t datalen = prep->datalen; 223*60dc5f1bSJames Bottomley char *datablob, *orig_datablob; 2245d0682beSSumit Garg int ret = 0; 2255d0682beSSumit Garg 2265d0682beSSumit Garg if (key_is_negative(key)) 2275d0682beSSumit Garg return -ENOKEY; 2285d0682beSSumit Garg p = key->payload.data[0]; 2295d0682beSSumit Garg if (!p->migratable) 2305d0682beSSumit Garg return -EPERM; 2315d0682beSSumit Garg if (datalen <= 0 || datalen > 32767 || !prep->data) 2325d0682beSSumit Garg return -EINVAL; 2335d0682beSSumit Garg 234*60dc5f1bSJames Bottomley orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL); 2355d0682beSSumit Garg if (!datablob) 2365d0682beSSumit Garg return -ENOMEM; 2375d0682beSSumit Garg 2385d0682beSSumit Garg new_p = trusted_payload_alloc(key); 2395d0682beSSumit Garg if (!new_p) { 2405d0682beSSumit Garg ret = -ENOMEM; 2415d0682beSSumit Garg goto out; 2425d0682beSSumit Garg } 2435d0682beSSumit Garg 2445d0682beSSumit Garg memcpy(datablob, prep->data, datalen); 2455d0682beSSumit Garg datablob[datalen] = '\0'; 246*60dc5f1bSJames Bottomley ret = datablob_parse(&datablob, new_p); 2475d0682beSSumit Garg if (ret != Opt_update) { 2485d0682beSSumit Garg ret = -EINVAL; 2495d0682beSSumit Garg kfree_sensitive(new_p); 2505d0682beSSumit Garg goto out; 2515d0682beSSumit Garg } 2525d0682beSSumit Garg 2535d0682beSSumit Garg /* copy old key values, and reseal with new pcrs */ 2545d0682beSSumit Garg new_p->migratable = p->migratable; 2555d0682beSSumit Garg new_p->key_len = p->key_len; 2565d0682beSSumit Garg memcpy(new_p->key, p->key, p->key_len); 2575d0682beSSumit Garg dump_payload(p); 2585d0682beSSumit Garg dump_payload(new_p); 2595d0682beSSumit Garg 2605d0682beSSumit Garg ret = static_call(trusted_key_seal)(new_p, datablob); 2615d0682beSSumit Garg if (ret < 0) { 2625d0682beSSumit Garg pr_info("key_seal failed (%d)\n", ret); 2635d0682beSSumit Garg kfree_sensitive(new_p); 2645d0682beSSumit Garg goto out; 2655d0682beSSumit Garg } 2665d0682beSSumit Garg 2675d0682beSSumit Garg rcu_assign_keypointer(key, new_p); 2685d0682beSSumit Garg call_rcu(&p->rcu, trusted_rcu_free); 2695d0682beSSumit Garg out: 270*60dc5f1bSJames Bottomley kfree_sensitive(orig_datablob); 2715d0682beSSumit Garg return ret; 2725d0682beSSumit Garg } 2735d0682beSSumit Garg 2745d0682beSSumit Garg /* 2755d0682beSSumit Garg * trusted_read - copy the sealed blob data to userspace in hex. 2765d0682beSSumit Garg * On success, return to userspace the trusted key datablob size. 2775d0682beSSumit Garg */ 2785d0682beSSumit Garg static long trusted_read(const struct key *key, char *buffer, 2795d0682beSSumit Garg size_t buflen) 2805d0682beSSumit Garg { 2815d0682beSSumit Garg const struct trusted_key_payload *p; 2825d0682beSSumit Garg char *bufp; 2835d0682beSSumit Garg int i; 2845d0682beSSumit Garg 2855d0682beSSumit Garg p = dereference_key_locked(key); 2865d0682beSSumit Garg if (!p) 2875d0682beSSumit Garg return -EINVAL; 2885d0682beSSumit Garg 2895d0682beSSumit Garg if (buffer && buflen >= 2 * p->blob_len) { 2905d0682beSSumit Garg bufp = buffer; 2915d0682beSSumit Garg for (i = 0; i < p->blob_len; i++) 2925d0682beSSumit Garg bufp = hex_byte_pack(bufp, p->blob[i]); 2935d0682beSSumit Garg } 2945d0682beSSumit Garg return 2 * p->blob_len; 2955d0682beSSumit Garg } 2965d0682beSSumit Garg 2975d0682beSSumit Garg /* 2985d0682beSSumit Garg * trusted_destroy - clear and free the key's payload 2995d0682beSSumit Garg */ 3005d0682beSSumit Garg static void trusted_destroy(struct key *key) 3015d0682beSSumit Garg { 3025d0682beSSumit Garg kfree_sensitive(key->payload.data[0]); 3035d0682beSSumit Garg } 3045d0682beSSumit Garg 3055d0682beSSumit Garg struct key_type key_type_trusted = { 3065d0682beSSumit Garg .name = "trusted", 3075d0682beSSumit Garg .instantiate = trusted_instantiate, 3085d0682beSSumit Garg .update = trusted_update, 3095d0682beSSumit Garg .destroy = trusted_destroy, 3105d0682beSSumit Garg .describe = user_describe, 3115d0682beSSumit Garg .read = trusted_read, 3125d0682beSSumit Garg }; 3135d0682beSSumit Garg EXPORT_SYMBOL_GPL(key_type_trusted); 3145d0682beSSumit Garg 3155d0682beSSumit Garg static int __init init_trusted(void) 3165d0682beSSumit Garg { 3175d0682beSSumit Garg int i, ret = 0; 3185d0682beSSumit Garg 3195d0682beSSumit Garg for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) { 3205d0682beSSumit Garg if (trusted_key_source && 3215d0682beSSumit Garg strncmp(trusted_key_source, trusted_key_sources[i].name, 3225d0682beSSumit Garg strlen(trusted_key_sources[i].name))) 3235d0682beSSumit Garg continue; 3245d0682beSSumit Garg 3255d0682beSSumit Garg static_call_update(trusted_key_init, 3265d0682beSSumit Garg trusted_key_sources[i].ops->init); 3275d0682beSSumit Garg static_call_update(trusted_key_seal, 3285d0682beSSumit Garg trusted_key_sources[i].ops->seal); 3295d0682beSSumit Garg static_call_update(trusted_key_unseal, 3305d0682beSSumit Garg trusted_key_sources[i].ops->unseal); 3315d0682beSSumit Garg static_call_update(trusted_key_get_random, 3325d0682beSSumit Garg trusted_key_sources[i].ops->get_random); 3335d0682beSSumit Garg static_call_update(trusted_key_exit, 3345d0682beSSumit Garg trusted_key_sources[i].ops->exit); 3355d0682beSSumit Garg migratable = trusted_key_sources[i].ops->migratable; 3365d0682beSSumit Garg 3375d0682beSSumit Garg ret = static_call(trusted_key_init)(); 3385d0682beSSumit Garg if (!ret) 3395d0682beSSumit Garg break; 3405d0682beSSumit Garg } 3415d0682beSSumit Garg 3425d0682beSSumit Garg /* 3435d0682beSSumit Garg * encrypted_keys.ko depends on successful load of this module even if 3445d0682beSSumit Garg * trusted key implementation is not found. 3455d0682beSSumit Garg */ 3465d0682beSSumit Garg if (ret == -ENODEV) 3475d0682beSSumit Garg return 0; 3485d0682beSSumit Garg 3495d0682beSSumit Garg return ret; 3505d0682beSSumit Garg } 3515d0682beSSumit Garg 3525d0682beSSumit Garg static void __exit cleanup_trusted(void) 3535d0682beSSumit Garg { 3545d0682beSSumit Garg static_call(trusted_key_exit)(); 3555d0682beSSumit Garg } 3565d0682beSSumit Garg 3575d0682beSSumit Garg late_initcall(init_trusted); 3585d0682beSSumit Garg module_exit(cleanup_trusted); 3595d0682beSSumit Garg 3605d0682beSSumit Garg MODULE_LICENSE("GPL"); 361