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

Merge tag 'tpmdd-next-v5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull tpm updates from Jarkko Sakkinen:

- Tightened validation of key hashes for SYSTEM_BLACKLIST_HASH_LIST. An
invalid hash format causes a compilation error. Previously, they got
included to the kernel binary but were silently ignored at run-time.

- Allow root user to append new hashes to the blacklist keyring.

- Trusted keys backed with Cryptographic Acceleration and Assurance
Module (CAAM), which part of some of the new NXP's SoC's. Now there
is total three hardware backends for trusted keys: TPM, ARM TEE and
CAAM.

- A scattered set of fixes and small improvements for the TPM driver.

* tag 'tpmdd-next-v5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
MAINTAINERS: add KEYS-TRUSTED-CAAM
doc: trusted-encrypted: describe new CAAM trust source
KEYS: trusted: Introduce support for NXP CAAM-based trusted keys
crypto: caam - add in-kernel interface for blob generator
crypto: caam - determine whether CAAM supports blob encap/decap
KEYS: trusted: allow use of kernel RNG for key material
KEYS: trusted: allow use of TEE as backend without TCG_TPM support
tpm: Add field upgrade mode support for Infineon TPM2 modules
tpm: Fix buffer access in tpm2_get_tpm_pt()
char: tpm: cr50_i2c: Suppress duplicated error message in .remove()
tpm: cr50: Add new device/vendor ID 0x504a6666
tpm: Remove read16/read32/write32 calls from tpm_tis_phy_ops
tpm: ibmvtpm: Correct the return value in tpm_ibmvtpm_probe()
tpm/tpm_ftpm_tee: Return true/false (not 1/0) from bool functions
certs: Explain the rationale to call panic()
certs: Allow root user to append signed hashes to the blacklist keyring
certs: Check that builtin blacklist hashes are valid
certs: Make blacklist_vet_description() more strict
certs: Factor out the blacklist hash creation
tools/certs: Add print-cert-tbs-hash.sh

+1054 -279
+11
Documentation/admin-guide/kernel-parameters.txt
··· 6081 6081 sources: 6082 6082 - "tpm" 6083 6083 - "tee" 6084 + - "caam" 6084 6085 If not specified then it defaults to iterating through 6085 6086 the trust source list starting with TPM and assigns the 6086 6087 first trust source as a backend which is initialized 6087 6088 successfully during iteration. 6089 + 6090 + trusted.rng= [KEYS] 6091 + Format: <string> 6092 + The RNG used to generate key material for trusted keys. 6093 + Can be one of: 6094 + - "kernel" 6095 + - the same value as trusted.source: "tpm" or "tee" 6096 + - "default" 6097 + If not specified, "default" is used. In this case, 6098 + the RNG's choice is left to each individual trust source. 6088 6099 6089 6100 tsc= Disable clocksource stability checks for TSC. 6090 6101 Format: <string>
+51 -9
Documentation/security/keys/trusted-encrypted.rst
··· 35 35 Rooted to Hardware Unique Key (HUK) which is generally burnt in on-chip 36 36 fuses and is accessible to TEE only. 37 37 38 + (3) CAAM (Cryptographic Acceleration and Assurance Module: IP on NXP SoCs) 39 + 40 + When High Assurance Boot (HAB) is enabled and the CAAM is in secure 41 + mode, trust is rooted to the OTPMK, a never-disclosed 256-bit key 42 + randomly generated and fused into each SoC at manufacturing time. 43 + Otherwise, a common fixed test key is used instead. 44 + 38 45 * Execution isolation 39 46 40 47 (1) TPM ··· 52 45 53 46 Customizable set of operations running in isolated execution 54 47 environment verified via Secure/Trusted boot process. 48 + 49 + (3) CAAM 50 + 51 + Fixed set of operations running in isolated execution environment. 55 52 56 53 * Optional binding to platform integrity state 57 54 ··· 74 63 Relies on Secure/Trusted boot process for platform integrity. It can 75 64 be extended with TEE based measured boot process. 76 65 66 + (3) CAAM 67 + 68 + Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs 69 + for platform integrity. 70 + 77 71 * Interfaces and APIs 78 72 79 73 (1) TPM ··· 90 74 TEEs have well-documented, standardized client interface and APIs. For 91 75 more details refer to ``Documentation/staging/tee.rst``. 92 76 77 + (3) CAAM 78 + 79 + Interface is specific to silicon vendor. 93 80 94 81 * Threat model 95 82 96 - The strength and appropriateness of a particular TPM or TEE for a given 83 + The strength and appropriateness of a particular trust source for a given 97 84 purpose must be assessed when using them to protect security-relevant data. 98 85 99 86 ··· 106 87 Trusted Keys 107 88 ------------ 108 89 109 - New keys are created from random numbers generated in the trust source. They 110 - are encrypted/decrypted using a child key in the storage key hierarchy. 111 - Encryption and decryption of the child key must be protected by a strong 112 - access control policy within the trust source. 90 + New keys are created from random numbers. They are encrypted/decrypted using 91 + a child key in the storage key hierarchy. Encryption and decryption of the 92 + child key must be protected by a strong access control policy within the 93 + trust source. The random number generator in use differs according to the 94 + selected trust source: 113 95 114 - * TPM (hardware device) based RNG 96 + * TPM: hardware device based RNG 115 97 116 - Strength of random numbers may vary from one device manufacturer to 117 - another. 98 + Keys are generated within the TPM. Strength of random numbers may vary 99 + from one device manufacturer to another. 118 100 119 - * TEE (OP-TEE based on Arm TrustZone) based RNG 101 + * TEE: OP-TEE based on Arm TrustZone based RNG 120 102 121 103 RNG is customizable as per platform needs. It can either be direct output 122 104 from platform specific hardware RNG or a software based Fortuna CSPRNG 123 105 which can be seeded via multiple entropy sources. 106 + 107 + * CAAM: Kernel RNG 108 + 109 + The normal kernel random number generator is used. To seed it from the 110 + CAAM HWRNG, enable CRYPTO_DEV_FSL_CAAM_RNG_API and ensure the device 111 + is probed. 112 + 113 + Users may override this by specifying ``trusted.rng=kernel`` on the kernel 114 + command-line to override the used RNG with the kernel's random number pool. 124 115 125 116 Encrypted Keys 126 117 -------------- ··· 217 188 "keyctl print" returns an ASCII hex copy of the sealed key, which is in format 218 189 specific to TEE device implementation. The key length for new keys is always 219 190 in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits). 191 + 192 + Trusted Keys usage: CAAM 193 + ------------------------ 194 + 195 + Usage:: 196 + 197 + keyctl add trusted name "new keylen" ring 198 + keyctl add trusted name "load hex_blob" ring 199 + keyctl print keyid 200 + 201 + "keyctl print" returns an ASCII hex copy of the sealed key, which is in a 202 + CAAM-specific format. The key length for new keys is always in bytes. 203 + Trusted Keys can be 32 - 128 bytes (256 - 1024 bits). 220 204 221 205 Encrypted Keys usage 222 206 --------------------
+11
MAINTAINERS
··· 4575 4575 S: Maintained 4576 4576 F: Documentation/admin-guide/module-signing.rst 4577 4577 F: certs/ 4578 + F: scripts/check-blacklist-hashes.awk 4578 4579 F: scripts/sign-file.c 4580 + F: tools/certs/ 4579 4581 4580 4582 CFAG12864B LCD DRIVER 4581 4583 M: Miguel Ojeda <ojeda@kernel.org> ··· 10866 10864 S: Supported 10867 10865 F: include/keys/trusted_tee.h 10868 10866 F: security/keys/trusted-keys/trusted_tee.c 10867 + 10868 + KEYS-TRUSTED-CAAM 10869 + M: Ahmad Fatoum <a.fatoum@pengutronix.de> 10870 + R: Pengutronix Kernel Team <kernel@pengutronix.de> 10871 + L: linux-integrity@vger.kernel.org 10872 + L: keyrings@vger.kernel.org 10873 + S: Maintained 10874 + F: include/keys/trusted_caam.h 10875 + F: security/keys/trusted-keys/trusted_caam.c 10869 10876 10870 10877 KEYS/KEYRINGS 10871 10878 M: David Howells <dhowells@redhat.com>
+1
certs/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 + /blacklist_hashes_checked 2 3 /extract-cert 3 4 /x509_certificate_list 4 5 /x509_revocation_list
+15 -2
certs/Kconfig
··· 104 104 help 105 105 If set, this option should be the filename of a list of hashes in the 106 106 form "<hash>", "<hash>", ... . This will be included into a C 107 - wrapper to incorporate the list into the kernel. Each <hash> should 108 - be a string of hex digits. 107 + wrapper to incorporate the list into the kernel. Each <hash> must be a 108 + string starting with a prefix ("tbs" or "bin"), then a colon (":"), and 109 + finally an even number of hexadecimal lowercase characters (up to 128). 110 + Certificate hashes can be generated with 111 + tools/certs/print-cert-tbs-hash.sh . 109 112 110 113 config SYSTEM_REVOCATION_LIST 111 114 bool "Provide system-wide ring of revocation certificates" ··· 126 123 If set, this option should be the filename of a PEM-formatted file 127 124 containing X.509 certificates to be included in the default blacklist 128 125 keyring. 126 + 127 + config SYSTEM_BLACKLIST_AUTH_UPDATE 128 + bool "Allow root to add signed blacklist keys" 129 + depends on SYSTEM_BLACKLIST_KEYRING 130 + depends on SYSTEM_DATA_VERIFICATION 131 + help 132 + If set, provide the ability to load new blacklist keys at run time if 133 + they are signed and vouched by a certificate from the builtin trusted 134 + keyring. The PKCS#7 signature of the description is set in the key 135 + payload. Blacklist keys cannot be removed. 129 136 130 137 endmenu
+13 -1
certs/Makefile
··· 7 7 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o 8 8 obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o 9 9 ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),) 10 + quiet_cmd_check_blacklist_hashes = CHECK $(patsubst "%",%,$(2)) 11 + cmd_check_blacklist_hashes = $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(2); touch $@ 12 + 13 + $(eval $(call config_filename,SYSTEM_BLACKLIST_HASH_LIST)) 14 + 15 + $(obj)/blacklist_hashes.o: $(obj)/blacklist_hashes_checked 16 + 17 + CFLAGS_blacklist_hashes.o += -I$(srctree) 18 + 19 + targets += blacklist_hashes_checked 20 + $(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE 21 + $(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST)) 10 22 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o 11 23 else 12 24 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o ··· 33 21 $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE 34 22 $(call if_changed,extract_certs) 35 23 36 - targets += x509_certificate_list 24 + targets += x509_certificate_list blacklist_hashes_checked 37 25 38 26 # If module signing is requested, say by allyesconfig, but a key has not been 39 27 # supplied, then one will need to be generated to make sure the build does not
+177 -48
certs/blacklist.c
··· 15 15 #include <linux/err.h> 16 16 #include <linux/seq_file.h> 17 17 #include <linux/uidgid.h> 18 + #include <linux/verification.h> 18 19 #include <keys/system_keyring.h> 19 20 #include "blacklist.h" 20 21 #include "common.h" 22 + 23 + /* 24 + * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), 25 + * the size of the currently longest supported hash algorithm is 512 bits, 26 + * which translates into 128 hex characters. 27 + */ 28 + #define MAX_HASH_LEN 128 29 + 30 + #define BLACKLIST_KEY_PERM (KEY_POS_SEARCH | KEY_POS_VIEW | \ 31 + KEY_USR_SEARCH | KEY_USR_VIEW) 32 + 33 + static const char tbs_prefix[] = "tbs"; 34 + static const char bin_prefix[] = "bin"; 21 35 22 36 static struct key *blacklist_keyring; 23 37 ··· 46 32 */ 47 33 static int blacklist_vet_description(const char *desc) 48 34 { 49 - int n = 0; 35 + int i, prefix_len, tbs_step = 0, bin_step = 0; 50 36 51 - if (*desc == ':') 52 - return -EINVAL; 53 - for (; *desc; desc++) 54 - if (*desc == ':') 55 - goto found_colon; 37 + /* The following algorithm only works if prefix lengths match. */ 38 + BUILD_BUG_ON(sizeof(tbs_prefix) != sizeof(bin_prefix)); 39 + prefix_len = sizeof(tbs_prefix) - 1; 40 + for (i = 0; *desc; desc++, i++) { 41 + if (*desc == ':') { 42 + if (tbs_step == prefix_len) 43 + goto found_colon; 44 + if (bin_step == prefix_len) 45 + goto found_colon; 46 + return -EINVAL; 47 + } 48 + if (i >= prefix_len) 49 + return -EINVAL; 50 + if (*desc == tbs_prefix[i]) 51 + tbs_step++; 52 + if (*desc == bin_prefix[i]) 53 + bin_step++; 54 + } 56 55 return -EINVAL; 57 56 58 57 found_colon: 59 58 desc++; 60 - for (; *desc; desc++) { 59 + for (i = 0; *desc && i < MAX_HASH_LEN; desc++, i++) { 61 60 if (!isxdigit(*desc) || isupper(*desc)) 62 61 return -EINVAL; 63 - n++; 64 62 } 63 + if (*desc) 64 + /* The hash is greater than MAX_HASH_LEN. */ 65 + return -ENOPKG; 65 66 66 - if (n == 0 || n & 1) 67 + /* Checks for an even number of hexadecimal characters. */ 68 + if (i == 0 || i & 1) 67 69 return -EINVAL; 68 70 return 0; 69 71 } 70 72 71 - /* 72 - * The hash to be blacklisted is expected to be in the description. There will 73 - * be no payload. 74 - */ 75 - static int blacklist_preparse(struct key_preparsed_payload *prep) 73 + static int blacklist_key_instantiate(struct key *key, 74 + struct key_preparsed_payload *prep) 76 75 { 77 - if (prep->datalen > 0) 78 - return -EINVAL; 79 - return 0; 76 + #ifdef CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE 77 + int err; 78 + #endif 79 + 80 + /* Sets safe default permissions for keys loaded by user space. */ 81 + key->perm = BLACKLIST_KEY_PERM; 82 + 83 + /* 84 + * Skips the authentication step for builtin hashes, they are not 85 + * signed but still trusted. 86 + */ 87 + if (key->flags & (1 << KEY_FLAG_BUILTIN)) 88 + goto out; 89 + 90 + #ifdef CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE 91 + /* 92 + * Verifies the description's PKCS#7 signature against the builtin 93 + * trusted keyring. 94 + */ 95 + err = verify_pkcs7_signature(key->description, 96 + strlen(key->description), prep->data, prep->datalen, 97 + NULL, VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL); 98 + if (err) 99 + return err; 100 + #else 101 + /* 102 + * It should not be possible to come here because the keyring doesn't 103 + * have KEY_USR_WRITE and the only other way to call this function is 104 + * for builtin hashes. 105 + */ 106 + WARN_ON_ONCE(1); 107 + return -EPERM; 108 + #endif 109 + 110 + out: 111 + return generic_key_instantiate(key, prep); 80 112 } 81 113 82 - static void blacklist_free_preparse(struct key_preparsed_payload *prep) 114 + static int blacklist_key_update(struct key *key, 115 + struct key_preparsed_payload *prep) 83 116 { 117 + return -EPERM; 84 118 } 85 119 86 120 static void blacklist_describe(const struct key *key, struct seq_file *m) ··· 139 77 static struct key_type key_type_blacklist = { 140 78 .name = "blacklist", 141 79 .vet_description = blacklist_vet_description, 142 - .preparse = blacklist_preparse, 143 - .free_preparse = blacklist_free_preparse, 144 - .instantiate = generic_key_instantiate, 80 + .instantiate = blacklist_key_instantiate, 81 + .update = blacklist_key_update, 145 82 .describe = blacklist_describe, 146 83 }; 147 84 85 + static char *get_raw_hash(const u8 *hash, size_t hash_len, 86 + enum blacklist_hash_type hash_type) 87 + { 88 + size_t type_len; 89 + const char *type_prefix; 90 + char *buffer, *p; 91 + 92 + switch (hash_type) { 93 + case BLACKLIST_HASH_X509_TBS: 94 + type_len = sizeof(tbs_prefix) - 1; 95 + type_prefix = tbs_prefix; 96 + break; 97 + case BLACKLIST_HASH_BINARY: 98 + type_len = sizeof(bin_prefix) - 1; 99 + type_prefix = bin_prefix; 100 + break; 101 + default: 102 + WARN_ON_ONCE(1); 103 + return ERR_PTR(-EINVAL); 104 + } 105 + buffer = kmalloc(type_len + 1 + hash_len * 2 + 1, GFP_KERNEL); 106 + if (!buffer) 107 + return ERR_PTR(-ENOMEM); 108 + p = memcpy(buffer, type_prefix, type_len); 109 + p += type_len; 110 + *p++ = ':'; 111 + bin2hex(p, hash, hash_len); 112 + p += hash_len * 2; 113 + *p = '\0'; 114 + return buffer; 115 + } 116 + 148 117 /** 149 - * mark_hash_blacklisted - Add a hash to the system blacklist 118 + * mark_raw_hash_blacklisted - Add a hash to the system blacklist 150 119 * @hash: The hash as a hex string with a type prefix (eg. "tbs:23aa429783") 151 120 */ 152 - int mark_hash_blacklisted(const char *hash) 121 + static int mark_raw_hash_blacklisted(const char *hash) 153 122 { 154 123 key_ref_t key; 155 124 ··· 189 96 hash, 190 97 NULL, 191 98 0, 192 - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 193 - KEY_USR_VIEW), 99 + BLACKLIST_KEY_PERM, 194 100 KEY_ALLOC_NOT_IN_QUOTA | 195 101 KEY_ALLOC_BUILT_IN); 196 102 if (IS_ERR(key)) { ··· 199 107 return 0; 200 108 } 201 109 110 + int mark_hash_blacklisted(const u8 *hash, size_t hash_len, 111 + enum blacklist_hash_type hash_type) 112 + { 113 + const char *buffer; 114 + int err; 115 + 116 + buffer = get_raw_hash(hash, hash_len, hash_type); 117 + if (IS_ERR(buffer)) 118 + return PTR_ERR(buffer); 119 + err = mark_raw_hash_blacklisted(buffer); 120 + kfree(buffer); 121 + return err; 122 + } 123 + 202 124 /** 203 125 * is_hash_blacklisted - Determine if a hash is blacklisted 204 126 * @hash: The hash to be checked as a binary blob 205 127 * @hash_len: The length of the binary hash 206 - * @type: Type of hash 128 + * @hash_type: Type of hash 207 129 */ 208 - int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type) 130 + int is_hash_blacklisted(const u8 *hash, size_t hash_len, 131 + enum blacklist_hash_type hash_type) 209 132 { 210 133 key_ref_t kref; 211 - size_t type_len = strlen(type); 212 - char *buffer, *p; 134 + const char *buffer; 213 135 int ret = 0; 214 136 215 - buffer = kmalloc(type_len + 1 + hash_len * 2 + 1, GFP_KERNEL); 216 - if (!buffer) 217 - return -ENOMEM; 218 - p = memcpy(buffer, type, type_len); 219 - p += type_len; 220 - *p++ = ':'; 221 - bin2hex(p, hash, hash_len); 222 - p += hash_len * 2; 223 - *p = 0; 224 - 137 + buffer = get_raw_hash(hash, hash_len, hash_type); 138 + if (IS_ERR(buffer)) 139 + return PTR_ERR(buffer); 225 140 kref = keyring_search(make_key_ref(blacklist_keyring, true), 226 141 &key_type_blacklist, buffer, false); 227 142 if (!IS_ERR(kref)) { ··· 243 144 244 145 int is_binary_blacklisted(const u8 *hash, size_t hash_len) 245 146 { 246 - if (is_hash_blacklisted(hash, hash_len, "bin") == -EKEYREJECTED) 147 + if (is_hash_blacklisted(hash, hash_len, BLACKLIST_HASH_BINARY) == 148 + -EKEYREJECTED) 247 149 return -EPERM; 248 150 249 151 return 0; ··· 266 166 NULL, 267 167 data, 268 168 size, 269 - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW), 270 - KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN); 169 + KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH 170 + | KEY_USR_VIEW, 171 + KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN 172 + | KEY_ALLOC_BYPASS_RESTRICTION); 271 173 272 174 if (IS_ERR(key)) { 273 175 pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); ··· 296 194 } 297 195 #endif 298 196 197 + static int restrict_link_for_blacklist(struct key *dest_keyring, 198 + const struct key_type *type, const union key_payload *payload, 199 + struct key *restrict_key) 200 + { 201 + if (type == &key_type_blacklist) 202 + return 0; 203 + return -EOPNOTSUPP; 204 + } 205 + 299 206 /* 300 207 * Initialise the blacklist 208 + * 209 + * The blacklist_init() function is registered as an initcall via 210 + * device_initcall(). As a result if the blacklist_init() function fails for 211 + * any reason the kernel continues to execute. While cleanly returning -ENODEV 212 + * could be acceptable for some non-critical kernel parts, if the blacklist 213 + * keyring fails to load it defeats the certificate/key based deny list for 214 + * signed modules. If a critical piece of security functionality that users 215 + * expect to be present fails to initialize, panic()ing is likely the right 216 + * thing to do. 301 217 */ 302 218 static int __init blacklist_init(void) 303 219 { 304 220 const char *const *bl; 221 + struct key_restriction *restriction; 305 222 306 223 if (register_key_type(&key_type_blacklist) < 0) 307 224 panic("Can't allocate system blacklist key type\n"); 308 225 226 + restriction = kzalloc(sizeof(*restriction), GFP_KERNEL); 227 + if (!restriction) 228 + panic("Can't allocate blacklist keyring restriction\n"); 229 + restriction->check = restrict_link_for_blacklist; 230 + 309 231 blacklist_keyring = 310 232 keyring_alloc(".blacklist", 311 233 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(), 312 - (KEY_POS_ALL & ~KEY_POS_SETATTR) | 313 - KEY_USR_VIEW | KEY_USR_READ | 314 - KEY_USR_SEARCH, 315 - KEY_ALLOC_NOT_IN_QUOTA | 234 + KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 235 + KEY_POS_WRITE | 236 + KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH 237 + #ifdef CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE 238 + | KEY_USR_WRITE 239 + #endif 240 + , KEY_ALLOC_NOT_IN_QUOTA | 316 241 KEY_ALLOC_SET_KEEP, 317 - NULL, NULL); 242 + restriction, NULL); 318 243 if (IS_ERR(blacklist_keyring)) 319 244 panic("Can't allocate system blacklist keyring\n"); 320 245 321 246 for (bl = blacklist_hashes; *bl; bl++) 322 - if (mark_hash_blacklisted(*bl) < 0) 247 + if (mark_raw_hash_blacklisted(*bl) < 0) 323 248 pr_err("- blacklisting failed\n"); 324 249 return 0; 325 250 }
+2 -1
crypto/asymmetric_keys/x509_public_key.c
··· 69 69 if (ret < 0) 70 70 goto error_2; 71 71 72 - ret = is_hash_blacklisted(sig->digest, sig->digest_size, "tbs"); 72 + ret = is_hash_blacklisted(sig->digest, sig->digest_size, 73 + BLACKLIST_HASH_X509_TBS); 73 74 if (ret == -EKEYREJECTED) { 74 75 pr_err("Cert %*phN is blacklisted\n", 75 76 sig->digest_size, sig->digest);
+15 -2
drivers/char/tpm/tpm2-cmd.c
··· 400 400 if (!rc) { 401 401 out = (struct tpm2_get_cap_out *) 402 402 &buf.data[TPM_HEADER_SIZE]; 403 - *value = be32_to_cpu(out->value); 403 + /* 404 + * To prevent failing boot up of some systems, Infineon TPM2.0 405 + * returns SUCCESS on TPM2_Startup in field upgrade mode. Also 406 + * the TPM2_Getcapability command returns a zero length list 407 + * in field upgrade mode. 408 + */ 409 + if (be32_to_cpu(out->property_cnt) > 0) 410 + *value = be32_to_cpu(out->value); 411 + else 412 + rc = -ENODATA; 404 413 } 405 414 tpm_buf_destroy(&buf); 406 415 return rc; ··· 754 745 rc = tpm2_get_cc_attrs_tbl(chip); 755 746 756 747 out: 757 - if (rc == TPM2_RC_UPGRADE) { 748 + /* 749 + * Infineon TPM in field upgrade mode will return no data for the number 750 + * of supported commands. 751 + */ 752 + if (rc == TPM2_RC_UPGRADE || rc == -ENODATA) { 758 753 dev_info(&chip->dev, "TPM in field upgrade mode, requires firmware upgrade\n"); 759 754 chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE; 760 755 rc = 0;
+1 -1
drivers/char/tpm/tpm_ftpm_tee.c
··· 177 177 178 178 static bool ftpm_tee_tpm_req_canceled(struct tpm_chip *chip, u8 status) 179 179 { 180 - return 0; 180 + return false; 181 181 } 182 182 183 183 static const struct tpm_class_ops ftpm_tee_tpm_ops = {
+1
drivers/char/tpm/tpm_ibmvtpm.c
··· 681 681 if (!wait_event_timeout(ibmvtpm->crq_queue.wq, 682 682 ibmvtpm->rtce_buf != NULL, 683 683 HZ)) { 684 + rc = -ENODEV; 684 685 dev_err(dev, "CRQ response timed out\n"); 685 686 goto init_irq_cleanup; 686 687 }
+29 -36
drivers/char/tpm/tpm_tis.c
··· 153 153 #endif 154 154 155 155 static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 156 - u8 *result) 156 + u8 *result, enum tpm_tis_io_mode io_mode) 157 157 { 158 158 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 159 + __le16 result_le16; 160 + __le32 result_le32; 159 161 160 - while (len--) 161 - *result++ = ioread8(phy->iobase + addr); 162 + switch (io_mode) { 163 + case TPM_TIS_PHYS_8: 164 + while (len--) 165 + *result++ = ioread8(phy->iobase + addr); 166 + break; 167 + case TPM_TIS_PHYS_16: 168 + result_le16 = cpu_to_le16(ioread16(phy->iobase + addr)); 169 + memcpy(result, &result_le16, sizeof(u16)); 170 + break; 171 + case TPM_TIS_PHYS_32: 172 + result_le32 = cpu_to_le32(ioread32(phy->iobase + addr)); 173 + memcpy(result, &result_le32, sizeof(u32)); 174 + break; 175 + } 162 176 163 177 return 0; 164 178 } 165 179 166 180 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 167 - const u8 *value) 181 + const u8 *value, enum tpm_tis_io_mode io_mode) 168 182 { 169 183 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 170 184 171 - while (len--) 172 - iowrite8(*value++, phy->iobase + addr); 173 - 174 - return 0; 175 - } 176 - 177 - static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result) 178 - { 179 - struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 180 - 181 - *result = ioread16(phy->iobase + addr); 182 - 183 - return 0; 184 - } 185 - 186 - static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result) 187 - { 188 - struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 189 - 190 - *result = ioread32(phy->iobase + addr); 191 - 192 - return 0; 193 - } 194 - 195 - static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) 196 - { 197 - struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 198 - 199 - iowrite32(value, phy->iobase + addr); 185 + switch (io_mode) { 186 + case TPM_TIS_PHYS_8: 187 + while (len--) 188 + iowrite8(*value++, phy->iobase + addr); 189 + break; 190 + case TPM_TIS_PHYS_16: 191 + return -EINVAL; 192 + case TPM_TIS_PHYS_32: 193 + iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase + addr); 194 + break; 195 + } 200 196 201 197 return 0; 202 198 } ··· 200 204 static const struct tpm_tis_phy_ops tpm_tcg = { 201 205 .read_bytes = tpm_tcg_read_bytes, 202 206 .write_bytes = tpm_tcg_write_bytes, 203 - .read16 = tpm_tcg_read16, 204 - .read32 = tpm_tcg_read32, 205 - .write32 = tpm_tcg_write32, 206 207 }; 207 208 208 209 static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
+46 -12
drivers/char/tpm/tpm_tis_core.h
··· 104 104 unsigned int timeout_max; /* usecs */ 105 105 }; 106 106 107 + /* 108 + * IO modes to indicate how many bytes should be read/written at once in the 109 + * tpm_tis_phy_ops read_bytes/write_bytes calls. Use TPM_TIS_PHYS_8 to 110 + * receive/transmit byte-wise, TPM_TIS_PHYS_16 for two bytes etc. 111 + */ 112 + enum tpm_tis_io_mode { 113 + TPM_TIS_PHYS_8, 114 + TPM_TIS_PHYS_16, 115 + TPM_TIS_PHYS_32, 116 + }; 117 + 107 118 struct tpm_tis_phy_ops { 119 + /* data is passed in little endian */ 108 120 int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len, 109 - u8 *result); 121 + u8 *result, enum tpm_tis_io_mode mode); 110 122 int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len, 111 - const u8 *value); 112 - int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result); 113 - int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result); 114 - int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src); 123 + const u8 *value, enum tpm_tis_io_mode mode); 115 124 }; 116 125 117 126 static inline int tpm_tis_read_bytes(struct tpm_tis_data *data, u32 addr, 118 127 u16 len, u8 *result) 119 128 { 120 - return data->phy_ops->read_bytes(data, addr, len, result); 129 + return data->phy_ops->read_bytes(data, addr, len, result, 130 + TPM_TIS_PHYS_8); 121 131 } 122 132 123 133 static inline int tpm_tis_read8(struct tpm_tis_data *data, u32 addr, u8 *result) 124 134 { 125 - return data->phy_ops->read_bytes(data, addr, 1, result); 135 + return data->phy_ops->read_bytes(data, addr, 1, result, TPM_TIS_PHYS_8); 126 136 } 127 137 128 138 static inline int tpm_tis_read16(struct tpm_tis_data *data, u32 addr, 129 139 u16 *result) 130 140 { 131 - return data->phy_ops->read16(data, addr, result); 141 + __le16 result_le; 142 + int rc; 143 + 144 + rc = data->phy_ops->read_bytes(data, addr, sizeof(u16), 145 + (u8 *)&result_le, TPM_TIS_PHYS_16); 146 + if (!rc) 147 + *result = le16_to_cpu(result_le); 148 + 149 + return rc; 132 150 } 133 151 134 152 static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr, 135 153 u32 *result) 136 154 { 137 - return data->phy_ops->read32(data, addr, result); 155 + __le32 result_le; 156 + int rc; 157 + 158 + rc = data->phy_ops->read_bytes(data, addr, sizeof(u32), 159 + (u8 *)&result_le, TPM_TIS_PHYS_32); 160 + if (!rc) 161 + *result = le32_to_cpu(result_le); 162 + 163 + return rc; 138 164 } 139 165 140 166 static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr, 141 167 u16 len, const u8 *value) 142 168 { 143 - return data->phy_ops->write_bytes(data, addr, len, value); 169 + return data->phy_ops->write_bytes(data, addr, len, value, 170 + TPM_TIS_PHYS_8); 144 171 } 145 172 146 173 static inline int tpm_tis_write8(struct tpm_tis_data *data, u32 addr, u8 value) 147 174 { 148 - return data->phy_ops->write_bytes(data, addr, 1, &value); 175 + return data->phy_ops->write_bytes(data, addr, 1, &value, 176 + TPM_TIS_PHYS_8); 149 177 } 150 178 151 179 static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr, 152 180 u32 value) 153 181 { 154 - return data->phy_ops->write32(data, addr, value); 182 + __le32 value_le; 183 + int rc; 184 + 185 + value_le = cpu_to_le32(value); 186 + rc = data->phy_ops->write_bytes(data, addr, sizeof(u32), 187 + (u8 *)&value_le, TPM_TIS_PHYS_32); 188 + return rc; 155 189 } 156 190 157 191 static inline bool is_bsw(void)
+6 -5
drivers/char/tpm/tpm_tis_i2c_cr50.c
··· 31 31 #define TPM_CR50_TIMEOUT_SHORT_MS 2 /* Short timeout during transactions */ 32 32 #define TPM_CR50_TIMEOUT_NOIRQ_MS 20 /* Timeout for TPM ready without IRQ */ 33 33 #define TPM_CR50_I2C_DID_VID 0x00281ae0L /* Device and vendor ID reg value */ 34 + #define TPM_TI50_I2C_DID_VID 0x504a6666L /* Device and vendor ID reg value */ 34 35 #define TPM_CR50_I2C_MAX_RETRIES 3 /* Max retries due to I2C errors */ 35 36 #define TPM_CR50_I2C_RETRY_DELAY_LO 55 /* Min usecs between retries on I2C */ 36 37 #define TPM_CR50_I2C_RETRY_DELAY_HI 65 /* Max usecs between retries on I2C */ ··· 743 742 } 744 743 745 744 vendor = le32_to_cpup((__le32 *)buf); 746 - if (vendor != TPM_CR50_I2C_DID_VID) { 745 + if (vendor != TPM_CR50_I2C_DID_VID && vendor != TPM_TI50_I2C_DID_VID) { 747 746 dev_err(dev, "Vendor ID did not match! ID was %08x\n", vendor); 748 747 tpm_cr50_release_locality(chip, true); 749 748 return -ENODEV; 750 749 } 751 750 752 - dev_info(dev, "cr50 TPM 2.0 (i2c 0x%02x irq %d id 0x%x)\n", 751 + dev_info(dev, "%s TPM 2.0 (i2c 0x%02x irq %d id 0x%x)\n", 752 + vendor == TPM_TI50_I2C_DID_VID ? "ti50" : "cr50", 753 753 client->addr, client->irq, vendor >> 16); 754 - 755 754 return tpm_chip_register(chip); 756 755 } 757 756 ··· 769 768 struct device *dev = &client->dev; 770 769 771 770 if (!chip) { 772 - dev_err(dev, "Could not get client data at remove\n"); 773 - return -ENODEV; 771 + dev_crit(dev, "Could not get client data at remove, memory corruption ahead\n"); 772 + return 0; 774 773 } 775 774 776 775 tpm_chip_unregister(chip);
-4
drivers/char/tpm/tpm_tis_spi.h
··· 31 31 extern int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, 32 32 u8 *in, const u8 *out); 33 33 34 - extern int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result); 35 - extern int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result); 36 - extern int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value); 37 - 38 34 #ifdef CONFIG_TCG_TIS_SPI_CR50 39 35 extern int cr50_spi_probe(struct spi_device *spi); 40 36 #else
+2 -5
drivers/char/tpm/tpm_tis_spi_cr50.c
··· 222 222 } 223 223 224 224 static int tpm_tis_spi_cr50_read_bytes(struct tpm_tis_data *data, u32 addr, 225 - u16 len, u8 *result) 225 + u16 len, u8 *result, enum tpm_tis_io_mode io_mode) 226 226 { 227 227 return tpm_tis_spi_cr50_transfer(data, addr, len, result, NULL); 228 228 } 229 229 230 230 static int tpm_tis_spi_cr50_write_bytes(struct tpm_tis_data *data, u32 addr, 231 - u16 len, const u8 *value) 231 + u16 len, const u8 *value, enum tpm_tis_io_mode io_mode) 232 232 { 233 233 return tpm_tis_spi_cr50_transfer(data, addr, len, NULL, value); 234 234 } ··· 236 236 static const struct tpm_tis_phy_ops tpm_spi_cr50_phy_ops = { 237 237 .read_bytes = tpm_tis_spi_cr50_read_bytes, 238 238 .write_bytes = tpm_tis_spi_cr50_write_bytes, 239 - .read16 = tpm_tis_spi_read16, 240 - .read32 = tpm_tis_spi_read32, 241 - .write32 = tpm_tis_spi_write32, 242 239 }; 243 240 244 241 static void cr50_print_fw_version(struct tpm_tis_data *data)
+2 -43
drivers/char/tpm/tpm_tis_spi_main.c
··· 141 141 } 142 142 143 143 static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, 144 - u16 len, u8 *result) 144 + u16 len, u8 *result, enum tpm_tis_io_mode io_mode) 145 145 { 146 146 return tpm_tis_spi_transfer(data, addr, len, result, NULL); 147 147 } 148 148 149 149 static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr, 150 - u16 len, const u8 *value) 150 + u16 len, const u8 *value, enum tpm_tis_io_mode io_mode) 151 151 { 152 152 return tpm_tis_spi_transfer(data, addr, len, NULL, value); 153 - } 154 - 155 - int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) 156 - { 157 - __le16 result_le; 158 - int rc; 159 - 160 - rc = data->phy_ops->read_bytes(data, addr, sizeof(u16), 161 - (u8 *)&result_le); 162 - if (!rc) 163 - *result = le16_to_cpu(result_le); 164 - 165 - return rc; 166 - } 167 - 168 - int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result) 169 - { 170 - __le32 result_le; 171 - int rc; 172 - 173 - rc = data->phy_ops->read_bytes(data, addr, sizeof(u32), 174 - (u8 *)&result_le); 175 - if (!rc) 176 - *result = le32_to_cpu(result_le); 177 - 178 - return rc; 179 - } 180 - 181 - int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value) 182 - { 183 - __le32 value_le; 184 - int rc; 185 - 186 - value_le = cpu_to_le32(value); 187 - rc = data->phy_ops->write_bytes(data, addr, sizeof(u32), 188 - (u8 *)&value_le); 189 - 190 - return rc; 191 153 } 192 154 193 155 int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy, ··· 167 205 static const struct tpm_tis_phy_ops tpm_spi_phy_ops = { 168 206 .read_bytes = tpm_tis_spi_read_bytes, 169 207 .write_bytes = tpm_tis_spi_write_bytes, 170 - .read16 = tpm_tis_spi_read16, 171 - .read32 = tpm_tis_spi_read32, 172 - .write32 = tpm_tis_spi_write32, 173 208 }; 174 209 175 210 static int tpm_tis_spi_probe(struct spi_device *dev)
+38 -60
drivers/char/tpm/tpm_tis_synquacer.c
··· 35 35 } 36 36 37 37 static int tpm_tis_synquacer_read_bytes(struct tpm_tis_data *data, u32 addr, 38 - u16 len, u8 *result) 38 + u16 len, u8 *result, 39 + enum tpm_tis_io_mode io_mode) 39 40 { 40 41 struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data); 41 - 42 - while (len--) 43 - *result++ = ioread8(phy->iobase + addr); 42 + switch (io_mode) { 43 + case TPM_TIS_PHYS_8: 44 + while (len--) 45 + *result++ = ioread8(phy->iobase + addr); 46 + break; 47 + case TPM_TIS_PHYS_16: 48 + result[1] = ioread8(phy->iobase + addr + 1); 49 + result[0] = ioread8(phy->iobase + addr); 50 + break; 51 + case TPM_TIS_PHYS_32: 52 + result[3] = ioread8(phy->iobase + addr + 3); 53 + result[2] = ioread8(phy->iobase + addr + 2); 54 + result[1] = ioread8(phy->iobase + addr + 1); 55 + result[0] = ioread8(phy->iobase + addr); 56 + break; 57 + } 44 58 45 59 return 0; 46 60 } 47 61 48 62 static int tpm_tis_synquacer_write_bytes(struct tpm_tis_data *data, u32 addr, 49 - u16 len, const u8 *value) 63 + u16 len, const u8 *value, 64 + enum tpm_tis_io_mode io_mode) 50 65 { 51 66 struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data); 52 - 53 - while (len--) 54 - iowrite8(*value++, phy->iobase + addr); 55 - 56 - return 0; 57 - } 58 - 59 - static int tpm_tis_synquacer_read16_bw(struct tpm_tis_data *data, 60 - u32 addr, u16 *result) 61 - { 62 - struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data); 63 - 64 - /* 65 - * Due to the limitation of SPI controller on SynQuacer, 66 - * 16/32 bits access must be done in byte-wise and descending order. 67 - */ 68 - *result = (ioread8(phy->iobase + addr + 1) << 8) | 69 - (ioread8(phy->iobase + addr)); 70 - 71 - return 0; 72 - } 73 - 74 - static int tpm_tis_synquacer_read32_bw(struct tpm_tis_data *data, 75 - u32 addr, u32 *result) 76 - { 77 - struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data); 78 - 79 - /* 80 - * Due to the limitation of SPI controller on SynQuacer, 81 - * 16/32 bits access must be done in byte-wise and descending order. 82 - */ 83 - *result = (ioread8(phy->iobase + addr + 3) << 24) | 84 - (ioread8(phy->iobase + addr + 2) << 16) | 85 - (ioread8(phy->iobase + addr + 1) << 8) | 86 - (ioread8(phy->iobase + addr)); 87 - 88 - return 0; 89 - } 90 - 91 - static int tpm_tis_synquacer_write32_bw(struct tpm_tis_data *data, 92 - u32 addr, u32 value) 93 - { 94 - struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data); 95 - 96 - /* 97 - * Due to the limitation of SPI controller on SynQuacer, 98 - * 16/32 bits access must be done in byte-wise and descending order. 99 - */ 100 - iowrite8(value >> 24, phy->iobase + addr + 3); 101 - iowrite8(value >> 16, phy->iobase + addr + 2); 102 - iowrite8(value >> 8, phy->iobase + addr + 1); 103 - iowrite8(value, phy->iobase + addr); 67 + switch (io_mode) { 68 + case TPM_TIS_PHYS_8: 69 + while (len--) 70 + iowrite8(*value++, phy->iobase + addr); 71 + break; 72 + case TPM_TIS_PHYS_16: 73 + return -EINVAL; 74 + case TPM_TIS_PHYS_32: 75 + /* 76 + * Due to the limitation of SPI controller on SynQuacer, 77 + * 16/32 bits access must be done in byte-wise and descending order. 78 + */ 79 + iowrite8(value[3], phy->iobase + addr + 3); 80 + iowrite8(value[2], phy->iobase + addr + 2); 81 + iowrite8(value[1], phy->iobase + addr + 1); 82 + iowrite8(value[0], phy->iobase + addr); 83 + break; 84 + } 104 85 105 86 return 0; 106 87 } ··· 89 108 static const struct tpm_tis_phy_ops tpm_tcg_bw = { 90 109 .read_bytes = tpm_tis_synquacer_read_bytes, 91 110 .write_bytes = tpm_tis_synquacer_write_bytes, 92 - .read16 = tpm_tis_synquacer_read16_bw, 93 - .read32 = tpm_tis_synquacer_read32_bw, 94 - .write32 = tpm_tis_synquacer_write32_bw, 95 111 }; 96 112 97 113 static int tpm_tis_synquacer_init(struct device *dev,
+3
drivers/crypto/caam/Kconfig
··· 151 151 Selecting this will register the SEC4 hardware rng to 152 152 the hw_random API for supplying the kernel entropy pool. 153 153 154 + config CRYPTO_DEV_FSL_CAAM_BLOB_GEN 155 + bool 156 + 154 157 endif # CRYPTO_DEV_FSL_CAAM_JR 155 158 156 159 endif # CRYPTO_DEV_FSL_CAAM
+1
drivers/crypto/caam/Makefile
··· 21 21 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o 22 22 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o 23 23 caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o 24 + caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_BLOB_GEN) += blob_gen.o 24 25 25 26 caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o 26 27 ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
+182
drivers/crypto/caam/blob_gen.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de> 4 + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de> 5 + */ 6 + 7 + #define pr_fmt(fmt) "caam blob_gen: " fmt 8 + 9 + #include <linux/device.h> 10 + #include <soc/fsl/caam-blob.h> 11 + 12 + #include "compat.h" 13 + #include "desc_constr.h" 14 + #include "desc.h" 15 + #include "error.h" 16 + #include "intern.h" 17 + #include "jr.h" 18 + #include "regs.h" 19 + 20 + #define CAAM_BLOB_DESC_BYTES_MAX \ 21 + /* Command to initialize & stating length of descriptor */ \ 22 + (CAAM_CMD_SZ + \ 23 + /* Command to append the key-modifier + key-modifier data */ \ 24 + CAAM_CMD_SZ + CAAM_BLOB_KEYMOD_LENGTH + \ 25 + /* Command to include input key + pointer to the input key */ \ 26 + CAAM_CMD_SZ + CAAM_PTR_SZ_MAX + \ 27 + /* Command to include output key + pointer to the output key */ \ 28 + CAAM_CMD_SZ + CAAM_PTR_SZ_MAX + \ 29 + /* Command describing the operation to perform */ \ 30 + CAAM_CMD_SZ) 31 + 32 + struct caam_blob_priv { 33 + struct device jrdev; 34 + }; 35 + 36 + struct caam_blob_job_result { 37 + int err; 38 + struct completion completion; 39 + }; 40 + 41 + static void caam_blob_job_done(struct device *dev, u32 *desc, u32 err, void *context) 42 + { 43 + struct caam_blob_job_result *res = context; 44 + int ecode = 0; 45 + 46 + dev_dbg(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 47 + 48 + if (err) 49 + ecode = caam_jr_strstatus(dev, err); 50 + 51 + res->err = ecode; 52 + 53 + /* 54 + * Upon completion, desc points to a buffer containing a CAAM job 55 + * descriptor which encapsulates data into an externally-storable 56 + * blob. 57 + */ 58 + complete(&res->completion); 59 + } 60 + 61 + int caam_process_blob(struct caam_blob_priv *priv, 62 + struct caam_blob_info *info, bool encap) 63 + { 64 + struct caam_blob_job_result testres; 65 + struct device *jrdev = &priv->jrdev; 66 + dma_addr_t dma_in, dma_out; 67 + int op = OP_PCLID_BLOB; 68 + size_t output_len; 69 + u32 *desc; 70 + int ret; 71 + 72 + if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH) 73 + return -EINVAL; 74 + 75 + if (encap) { 76 + op |= OP_TYPE_ENCAP_PROTOCOL; 77 + output_len = info->input_len + CAAM_BLOB_OVERHEAD; 78 + } else { 79 + op |= OP_TYPE_DECAP_PROTOCOL; 80 + output_len = info->input_len - CAAM_BLOB_OVERHEAD; 81 + } 82 + 83 + desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA); 84 + if (!desc) 85 + return -ENOMEM; 86 + 87 + dma_in = dma_map_single(jrdev, info->input, info->input_len, 88 + DMA_TO_DEVICE); 89 + if (dma_mapping_error(jrdev, dma_in)) { 90 + dev_err(jrdev, "unable to map input DMA buffer\n"); 91 + ret = -ENOMEM; 92 + goto out_free; 93 + } 94 + 95 + dma_out = dma_map_single(jrdev, info->output, output_len, 96 + DMA_FROM_DEVICE); 97 + if (dma_mapping_error(jrdev, dma_out)) { 98 + dev_err(jrdev, "unable to map output DMA buffer\n"); 99 + ret = -ENOMEM; 100 + goto out_unmap_in; 101 + } 102 + 103 + /* 104 + * A data blob is encrypted using a blob key (BK); a random number. 105 + * The BK is used as an AES-CCM key. The initial block (B0) and the 106 + * initial counter (Ctr0) are generated automatically and stored in 107 + * Class 1 Context DWords 0+1+2+3. The random BK is stored in the 108 + * Class 1 Key Register. Operation Mode is set to AES-CCM. 109 + */ 110 + 111 + init_job_desc(desc, 0); 112 + append_key_as_imm(desc, info->key_mod, info->key_mod_len, 113 + info->key_mod_len, CLASS_2 | KEY_DEST_CLASS_REG); 114 + append_seq_in_ptr_intlen(desc, dma_in, info->input_len, 0); 115 + append_seq_out_ptr_intlen(desc, dma_out, output_len, 0); 116 + append_operation(desc, op); 117 + 118 + print_hex_dump_debug("data@"__stringify(__LINE__)": ", 119 + DUMP_PREFIX_ADDRESS, 16, 1, info->input, 120 + info->input_len, false); 121 + print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ", 122 + DUMP_PREFIX_ADDRESS, 16, 1, desc, 123 + desc_bytes(desc), false); 124 + 125 + testres.err = 0; 126 + init_completion(&testres.completion); 127 + 128 + ret = caam_jr_enqueue(jrdev, desc, caam_blob_job_done, &testres); 129 + if (ret == -EINPROGRESS) { 130 + wait_for_completion(&testres.completion); 131 + ret = testres.err; 132 + print_hex_dump_debug("output@"__stringify(__LINE__)": ", 133 + DUMP_PREFIX_ADDRESS, 16, 1, info->output, 134 + output_len, false); 135 + } 136 + 137 + if (ret == 0) 138 + info->output_len = output_len; 139 + 140 + dma_unmap_single(jrdev, dma_out, output_len, DMA_FROM_DEVICE); 141 + out_unmap_in: 142 + dma_unmap_single(jrdev, dma_in, info->input_len, DMA_TO_DEVICE); 143 + out_free: 144 + kfree(desc); 145 + 146 + return ret; 147 + } 148 + EXPORT_SYMBOL(caam_process_blob); 149 + 150 + struct caam_blob_priv *caam_blob_gen_init(void) 151 + { 152 + struct caam_drv_private *ctrlpriv; 153 + struct device *jrdev; 154 + 155 + /* 156 + * caam_blob_gen_init() may expectedly fail with -ENODEV, e.g. when 157 + * CAAM driver didn't probe or when SoC lacks BLOB support. An 158 + * error would be harsh in this case, so we stick to info level. 159 + */ 160 + 161 + jrdev = caam_jr_alloc(); 162 + if (IS_ERR(jrdev)) { 163 + pr_info("job ring requested, but none currently available\n"); 164 + return ERR_PTR(-ENODEV); 165 + } 166 + 167 + ctrlpriv = dev_get_drvdata(jrdev->parent); 168 + if (!ctrlpriv->blob_present) { 169 + dev_info(jrdev, "no hardware blob generation support\n"); 170 + caam_jr_free(jrdev); 171 + return ERR_PTR(-ENODEV); 172 + } 173 + 174 + return container_of(jrdev, struct caam_blob_priv, jrdev); 175 + } 176 + EXPORT_SYMBOL(caam_blob_gen_init); 177 + 178 + void caam_blob_gen_exit(struct caam_blob_priv *priv) 179 + { 180 + caam_jr_free(&priv->jrdev); 181 + } 182 + EXPORT_SYMBOL(caam_blob_gen_exit);
+15 -2
drivers/crypto/caam/ctrl.c
··· 820 820 return -ENOMEM; 821 821 } 822 822 823 - if (ctrlpriv->era < 10) 823 + comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ls); 824 + ctrlpriv->blob_present = !!(comp_params & CTPR_LS_BLOB); 825 + 826 + /* 827 + * Some SoCs like the LS1028A (non-E) indicate CTPR_LS_BLOB support, 828 + * but fail when actually using it due to missing AES support, so 829 + * check both here. 830 + */ 831 + if (ctrlpriv->era < 10) { 824 832 rng_vid = (rd_reg32(&ctrl->perfmon.cha_id_ls) & 825 833 CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; 826 - else 834 + ctrlpriv->blob_present = ctrlpriv->blob_present && 835 + (rd_reg32(&ctrl->perfmon.cha_num_ls) & CHA_ID_LS_AES_MASK); 836 + } else { 827 837 rng_vid = (rd_reg32(&ctrl->vreg.rng) & CHA_VER_VID_MASK) >> 828 838 CHA_VER_VID_SHIFT; 839 + ctrlpriv->blob_present = ctrlpriv->blob_present && 840 + (rd_reg32(&ctrl->vreg.aesa) & CHA_VER_MISC_AES_NUM_MASK); 841 + } 829 842 830 843 /* 831 844 * If SEC has RNG version >= 4 and RNG state handle has not been
+1
drivers/crypto/caam/intern.h
··· 92 92 */ 93 93 u8 total_jobrs; /* Total Job Rings in device */ 94 94 u8 qi_present; /* Nonzero if QI present in device */ 95 + u8 blob_present; /* Nonzero if BLOB support present in device */ 95 96 u8 mc_en; /* Nonzero if MC f/w is active */ 96 97 int secvio_irq; /* Security violation interrupt number */ 97 98 int virt_en; /* Virtualization enabled in CAAM */
+3 -1
drivers/crypto/caam/regs.h
··· 320 320 #define CHA_VER_VID_MASK (0xffull << CHA_VER_VID_SHIFT) 321 321 322 322 /* CHA Miscellaneous Information - AESA_MISC specific */ 323 - #define CHA_VER_MISC_AES_GCM BIT(1 + CHA_VER_MISC_SHIFT) 323 + #define CHA_VER_MISC_AES_NUM_MASK GENMASK(7, 0) 324 + #define CHA_VER_MISC_AES_GCM BIT(1 + CHA_VER_MISC_SHIFT) 324 325 325 326 /* CHA Miscellaneous Information - PKHA_MISC specific */ 326 327 #define CHA_VER_MISC_PKHA_NO_CRYPT BIT(7 + CHA_VER_MISC_SHIFT) ··· 415 414 #define CTPR_MS_PG_SZ_MASK 0x10 416 415 #define CTPR_MS_PG_SZ_SHIFT 4 417 416 u32 comp_parms_ms; /* CTPR - Compile Parameters Register */ 417 + #define CTPR_LS_BLOB BIT(1) 418 418 u32 comp_parms_ls; /* CTPR - Compile Parameters Register */ 419 419 u64 rsvd1[2]; 420 420
+11 -3
include/keys/system_keyring.h
··· 10 10 11 11 #include <linux/key.h> 12 12 13 + enum blacklist_hash_type { 14 + /* TBSCertificate hash */ 15 + BLACKLIST_HASH_X509_TBS = 1, 16 + /* Raw data hash */ 17 + BLACKLIST_HASH_BINARY = 2, 18 + }; 19 + 13 20 #ifdef CONFIG_SYSTEM_TRUSTED_KEYRING 14 21 15 22 extern int restrict_link_by_builtin_trusted(struct key *keyring, ··· 61 54 62 55 extern struct pkcs7_message *pkcs7; 63 56 #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING 64 - extern int mark_hash_blacklisted(const char *hash); 57 + extern int mark_hash_blacklisted(const u8 *hash, size_t hash_len, 58 + enum blacklist_hash_type hash_type); 65 59 extern int is_hash_blacklisted(const u8 *hash, size_t hash_len, 66 - const char *type); 60 + enum blacklist_hash_type hash_type); 67 61 extern int is_binary_blacklisted(const u8 *hash, size_t hash_len); 68 62 #else 69 63 static inline int is_hash_blacklisted(const u8 *hash, size_t hash_len, 70 - const char *type) 64 + enum blacklist_hash_type hash_type) 71 65 { 72 66 return 0; 73 67 }
+1 -1
include/keys/trusted-type.h
··· 64 64 /* Unseal a key. */ 65 65 int (*unseal)(struct trusted_key_payload *p, char *datablob); 66 66 67 - /* Get a randomized key. */ 67 + /* Optional: Get a randomized key. */ 68 68 int (*get_random)(unsigned char *key, size_t key_len); 69 69 70 70 /* Exit key interface. */
+11
include/keys/trusted_caam.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de> 4 + */ 5 + 6 + #ifndef __CAAM_TRUSTED_KEY_H 7 + #define __CAAM_TRUSTED_KEY_H 8 + 9 + extern struct trusted_key_ops trusted_key_caam_ops; 10 + 11 + #endif
+103
include/soc/fsl/caam-blob.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2020 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de> 4 + */ 5 + 6 + #ifndef __CAAM_BLOB_GEN 7 + #define __CAAM_BLOB_GEN 8 + 9 + #include <linux/types.h> 10 + #include <linux/errno.h> 11 + 12 + #define CAAM_BLOB_KEYMOD_LENGTH 16 13 + #define CAAM_BLOB_OVERHEAD (32 + 16) 14 + #define CAAM_BLOB_MAX_LEN 4096 15 + 16 + struct caam_blob_priv; 17 + 18 + /** 19 + * struct caam_blob_info - information for CAAM blobbing 20 + * @input: pointer to input buffer (must be DMAable) 21 + * @input_len: length of @input buffer in bytes. 22 + * @output: pointer to output buffer (must be DMAable) 23 + * @output_len: length of @output buffer in bytes. 24 + * @key_mod: key modifier 25 + * @key_mod_len: length of @key_mod in bytes. 26 + * May not exceed %CAAM_BLOB_KEYMOD_LENGTH 27 + */ 28 + struct caam_blob_info { 29 + void *input; 30 + size_t input_len; 31 + 32 + void *output; 33 + size_t output_len; 34 + 35 + const void *key_mod; 36 + size_t key_mod_len; 37 + }; 38 + 39 + /** 40 + * caam_blob_gen_init - initialize blob generation 41 + * Return: pointer to new &struct caam_blob_priv instance on success 42 + * and ``ERR_PTR(-ENODEV)`` if CAAM has no hardware blobbing support 43 + * or no job ring could be allocated. 44 + */ 45 + struct caam_blob_priv *caam_blob_gen_init(void); 46 + 47 + /** 48 + * caam_blob_gen_exit - free blob generation resources 49 + * @priv: instance returned by caam_blob_gen_init() 50 + */ 51 + void caam_blob_gen_exit(struct caam_blob_priv *priv); 52 + 53 + /** 54 + * caam_process_blob - encapsulate or decapsulate blob 55 + * @priv: instance returned by caam_blob_gen_init() 56 + * @info: pointer to blobbing info describing key, blob and 57 + * key modifier buffers. 58 + * @encap: true for encapsulation, false for decapsulation 59 + * 60 + * Return: %0 and sets ``info->output_len`` on success and a negative 61 + * error code otherwise. 62 + */ 63 + int caam_process_blob(struct caam_blob_priv *priv, 64 + struct caam_blob_info *info, bool encap); 65 + 66 + /** 67 + * caam_encap_blob - encapsulate blob 68 + * @priv: instance returned by caam_blob_gen_init() 69 + * @info: pointer to blobbing info describing input key, 70 + * output blob and key modifier buffers. 71 + * 72 + * Return: %0 and sets ``info->output_len`` on success and 73 + * a negative error code otherwise. 74 + */ 75 + static inline int caam_encap_blob(struct caam_blob_priv *priv, 76 + struct caam_blob_info *info) 77 + { 78 + if (info->output_len < info->input_len + CAAM_BLOB_OVERHEAD) 79 + return -EINVAL; 80 + 81 + return caam_process_blob(priv, info, true); 82 + } 83 + 84 + /** 85 + * caam_decap_blob - decapsulate blob 86 + * @priv: instance returned by caam_blob_gen_init() 87 + * @info: pointer to blobbing info describing output key, 88 + * input blob and key modifier buffers. 89 + * 90 + * Return: %0 and sets ``info->output_len`` on success and 91 + * a negative error code otherwise. 92 + */ 93 + static inline int caam_decap_blob(struct caam_blob_priv *priv, 94 + struct caam_blob_info *info) 95 + { 96 + if (info->input_len < CAAM_BLOB_OVERHEAD || 97 + info->output_len < info->input_len - CAAM_BLOB_OVERHEAD) 98 + return -EINVAL; 99 + 100 + return caam_process_blob(priv, info, false); 101 + } 102 + 103 + #endif
+37
scripts/check-blacklist-hashes.awk
··· 1 + #!/usr/bin/awk -f 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Copyright © 2020, Microsoft Corporation. All rights reserved. 5 + # 6 + # Author: Mickaël Salaün <mic@linux.microsoft.com> 7 + # 8 + # Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of 9 + # hash strings. Such string must start with a prefix ("tbs" or "bin"), then a 10 + # colon (":"), and finally an even number of hexadecimal lowercase characters 11 + # (up to 128). 12 + 13 + BEGIN { 14 + RS = "," 15 + } 16 + { 17 + if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) { 18 + print "Not a string (item " NR "):", $0; 19 + exit 1; 20 + } 21 + if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) { 22 + print "Unknown prefix (item " NR "):", part1[1]; 23 + exit 1; 24 + } 25 + if (!match(part2[2], "^([0-9a-f]+)$", part3)) { 26 + print "Not a lowercase hexadecimal string (item " NR "):", part2[2]; 27 + exit 1; 28 + } 29 + if (length(part3[1]) > 128) { 30 + print "Hash string too long (item " NR "):", part3[1]; 31 + exit 1; 32 + } 33 + if (length(part3[1]) % 2 == 1) { 34 + print "Not an even number of hexadecimal characters (item " NR "):", part3[1]; 35 + exit 1; 36 + } 37 + }
+2 -24
security/integrity/platform_certs/keyring_handler.c
··· 17 17 static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; 18 18 19 19 /* 20 - * Blacklist a hash. 21 - */ 22 - static __init void uefi_blacklist_hash(const char *source, const void *data, 23 - size_t len, const char *type, 24 - size_t type_len) 25 - { 26 - char *hash, *p; 27 - 28 - hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL); 29 - if (!hash) 30 - return; 31 - p = memcpy(hash, type, type_len); 32 - p += type_len; 33 - bin2hex(p, data, len); 34 - p += len * 2; 35 - *p = 0; 36 - 37 - mark_hash_blacklisted(hash); 38 - kfree(hash); 39 - } 40 - 41 - /* 42 20 * Blacklist an X509 TBS hash. 43 21 */ 44 22 static __init void uefi_blacklist_x509_tbs(const char *source, 45 23 const void *data, size_t len) 46 24 { 47 - uefi_blacklist_hash(source, data, len, "tbs:", 4); 25 + mark_hash_blacklisted(data, len, BLACKLIST_HASH_X509_TBS); 48 26 } 49 27 50 28 /* ··· 31 53 static __init void uefi_blacklist_binary(const char *source, 32 54 const void *data, size_t len) 33 55 { 34 - uefi_blacklist_hash(source, data, len, "bin:", 4); 56 + mark_hash_blacklisted(data, len, BLACKLIST_HASH_BINARY); 35 57 } 36 58 37 59 /*
+7 -11
security/keys/Kconfig
··· 70 70 71 71 config TRUSTED_KEYS 72 72 tristate "TRUSTED KEYS" 73 - depends on KEYS && TCG_TPM 74 - select CRYPTO 75 - select CRYPTO_HMAC 76 - select CRYPTO_SHA1 77 - select CRYPTO_HASH_INFO 78 - select ASN1_ENCODER 79 - select OID_REGISTRY 80 - select ASN1 73 + depends on KEYS 81 74 help 82 75 This option provides support for creating, sealing, and unsealing 83 76 keys in the kernel. Trusted keys are random number symmetric keys, 84 - generated and RSA-sealed by the TPM. The TPM only unseals the keys, 85 - if the boot PCRs and other criteria match. Userspace will only ever 86 - see encrypted blobs. 77 + generated and sealed by a trust source selected at kernel boot-time. 78 + Userspace will only ever see encrypted blobs. 87 79 88 80 If you are unsure as to whether this is required, answer N. 81 + 82 + if TRUSTED_KEYS 83 + source "security/keys/trusted-keys/Kconfig" 84 + endif 89 85 90 86 config ENCRYPTED_KEYS 91 87 tristate "ENCRYPTED KEYS"
+38
security/keys/trusted-keys/Kconfig
··· 1 + config TRUSTED_KEYS_TPM 2 + bool "TPM-based trusted keys" 3 + depends on TCG_TPM >= TRUSTED_KEYS 4 + default y 5 + select CRYPTO 6 + select CRYPTO_HMAC 7 + select CRYPTO_SHA1 8 + select CRYPTO_HASH_INFO 9 + select ASN1_ENCODER 10 + select OID_REGISTRY 11 + select ASN1 12 + help 13 + Enable use of the Trusted Platform Module (TPM) as trusted key 14 + backend. Trusted keys are random number symmetric keys, 15 + which will be generated and RSA-sealed by the TPM. 16 + The TPM only unseals the keys, if the boot PCRs and other 17 + criteria match. 18 + 19 + config TRUSTED_KEYS_TEE 20 + bool "TEE-based trusted keys" 21 + depends on TEE >= TRUSTED_KEYS 22 + default y 23 + help 24 + Enable use of the Trusted Execution Environment (TEE) as trusted 25 + key backend. 26 + 27 + config TRUSTED_KEYS_CAAM 28 + bool "CAAM-based trusted keys" 29 + depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS 30 + select CRYPTO_DEV_FSL_CAAM_BLOB_GEN 31 + default y 32 + help 33 + Enable use of NXP's Cryptographic Accelerator and Assurance Module 34 + (CAAM) as trusted key backend. 35 + 36 + if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE && !TRUSTED_KEYS_CAAM 37 + comment "No trust source selected!" 38 + endif
+6 -4
security/keys/trusted-keys/Makefile
··· 5 5 6 6 obj-$(CONFIG_TRUSTED_KEYS) += trusted.o 7 7 trusted-y += trusted_core.o 8 - trusted-y += trusted_tpm1.o 8 + trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm1.o 9 9 10 10 $(obj)/trusted_tpm2.o: $(obj)/tpm2key.asn1.h 11 - trusted-y += trusted_tpm2.o 12 - trusted-y += tpm2key.asn1.o 11 + trusted-$(CONFIG_TRUSTED_KEYS_TPM) += trusted_tpm2.o 12 + trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o 13 13 14 - trusted-$(CONFIG_TEE) += trusted_tee.o 14 + trusted-$(CONFIG_TRUSTED_KEYS_TEE) += trusted_tee.o 15 + 16 + trusted-$(CONFIG_TRUSTED_KEYS_CAAM) += trusted_caam.o
+80
security/keys/trusted-keys/trusted_caam.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de> 4 + */ 5 + 6 + #include <keys/trusted_caam.h> 7 + #include <keys/trusted-type.h> 8 + #include <linux/build_bug.h> 9 + #include <linux/key-type.h> 10 + #include <soc/fsl/caam-blob.h> 11 + 12 + static struct caam_blob_priv *blobifier; 13 + 14 + #define KEYMOD "SECURE_KEY" 15 + 16 + static_assert(MAX_KEY_SIZE + CAAM_BLOB_OVERHEAD <= CAAM_BLOB_MAX_LEN); 17 + static_assert(MAX_BLOB_SIZE <= CAAM_BLOB_MAX_LEN); 18 + 19 + static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob) 20 + { 21 + int ret; 22 + struct caam_blob_info info = { 23 + .input = p->key, .input_len = p->key_len, 24 + .output = p->blob, .output_len = MAX_BLOB_SIZE, 25 + .key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1, 26 + }; 27 + 28 + ret = caam_encap_blob(blobifier, &info); 29 + if (ret) 30 + return ret; 31 + 32 + p->blob_len = info.output_len; 33 + return 0; 34 + } 35 + 36 + static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob) 37 + { 38 + int ret; 39 + struct caam_blob_info info = { 40 + .input = p->blob, .input_len = p->blob_len, 41 + .output = p->key, .output_len = MAX_KEY_SIZE, 42 + .key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1, 43 + }; 44 + 45 + ret = caam_decap_blob(blobifier, &info); 46 + if (ret) 47 + return ret; 48 + 49 + p->key_len = info.output_len; 50 + return 0; 51 + } 52 + 53 + static int trusted_caam_init(void) 54 + { 55 + int ret; 56 + 57 + blobifier = caam_blob_gen_init(); 58 + if (IS_ERR(blobifier)) 59 + return PTR_ERR(blobifier); 60 + 61 + ret = register_key_type(&key_type_trusted); 62 + if (ret) 63 + caam_blob_gen_exit(blobifier); 64 + 65 + return ret; 66 + } 67 + 68 + static void trusted_caam_exit(void) 69 + { 70 + unregister_key_type(&key_type_trusted); 71 + caam_blob_gen_exit(blobifier); 72 + } 73 + 74 + struct trusted_key_ops trusted_key_caam_ops = { 75 + .migratable = 0, /* non-migratable */ 76 + .init = trusted_caam_init, 77 + .seal = trusted_caam_seal, 78 + .unseal = trusted_caam_unseal, 79 + .exit = trusted_caam_exit, 80 + };
+41 -4
security/keys/trusted-keys/trusted_core.c
··· 9 9 #include <keys/user-type.h> 10 10 #include <keys/trusted-type.h> 11 11 #include <keys/trusted_tee.h> 12 + #include <keys/trusted_caam.h> 12 13 #include <keys/trusted_tpm.h> 13 14 #include <linux/capability.h> 14 15 #include <linux/err.h> ··· 17 16 #include <linux/key-type.h> 18 17 #include <linux/module.h> 19 18 #include <linux/parser.h> 19 + #include <linux/random.h> 20 20 #include <linux/rcupdate.h> 21 21 #include <linux/slab.h> 22 22 #include <linux/static_call.h> 23 23 #include <linux/string.h> 24 24 #include <linux/uaccess.h> 25 25 26 + static char *trusted_rng = "default"; 27 + module_param_named(rng, trusted_rng, charp, 0); 28 + MODULE_PARM_DESC(rng, "Select trusted key RNG"); 29 + 26 30 static char *trusted_key_source; 27 31 module_param_named(source, trusted_key_source, charp, 0); 28 - MODULE_PARM_DESC(source, "Select trusted keys source (tpm or tee)"); 32 + MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee or caam)"); 29 33 30 34 static const struct trusted_key_source trusted_key_sources[] = { 31 - #if IS_REACHABLE(CONFIG_TCG_TPM) 35 + #if defined(CONFIG_TRUSTED_KEYS_TPM) 32 36 { "tpm", &trusted_key_tpm_ops }, 33 37 #endif 34 - #if IS_REACHABLE(CONFIG_TEE) 38 + #if defined(CONFIG_TRUSTED_KEYS_TEE) 35 39 { "tee", &trusted_key_tee_ops }, 40 + #endif 41 + #if defined(CONFIG_TRUSTED_KEYS_CAAM) 42 + { "caam", &trusted_key_caam_ops }, 36 43 #endif 37 44 }; 38 45 ··· 321 312 }; 322 313 EXPORT_SYMBOL_GPL(key_type_trusted); 323 314 315 + static int kernel_get_random(unsigned char *key, size_t key_len) 316 + { 317 + return get_random_bytes_wait(key, key_len) ?: key_len; 318 + } 319 + 324 320 static int __init init_trusted(void) 325 321 { 322 + int (*get_random)(unsigned char *key, size_t key_len); 326 323 int i, ret = 0; 327 324 328 325 for (i = 0; i < ARRAY_SIZE(trusted_key_sources); i++) { ··· 337 322 strlen(trusted_key_sources[i].name))) 338 323 continue; 339 324 325 + /* 326 + * We always support trusted.rng="kernel" and "default" as 327 + * well as trusted.rng=$trusted.source if the trust source 328 + * defines its own get_random callback. 329 + */ 330 + get_random = trusted_key_sources[i].ops->get_random; 331 + if (trusted_rng && strcmp(trusted_rng, "default")) { 332 + if (!strcmp(trusted_rng, "kernel")) { 333 + get_random = kernel_get_random; 334 + } else if (strcmp(trusted_rng, trusted_key_sources[i].name) || 335 + !get_random) { 336 + pr_warn("Unsupported RNG. Supported: kernel"); 337 + if (get_random) 338 + pr_cont(", %s", trusted_key_sources[i].name); 339 + pr_cont(", default\n"); 340 + return -EINVAL; 341 + } 342 + } 343 + 344 + if (!get_random) 345 + get_random = kernel_get_random; 346 + 340 347 static_call_update(trusted_key_init, 341 348 trusted_key_sources[i].ops->init); 342 349 static_call_update(trusted_key_seal, ··· 366 329 static_call_update(trusted_key_unseal, 367 330 trusted_key_sources[i].ops->unseal); 368 331 static_call_update(trusted_key_get_random, 369 - trusted_key_sources[i].ops->get_random); 332 + get_random); 370 333 static_call_update(trusted_key_exit, 371 334 trusted_key_sources[i].ops->exit); 372 335 migratable = trusted_key_sources[i].ops->migratable;
+91
tools/certs/print-cert-tbs-hash.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Copyright © 2020, Microsoft Corporation. All rights reserved. 5 + # 6 + # Author: Mickaël Salaün <mic@linux.microsoft.com> 7 + # 8 + # Compute and print the To Be Signed (TBS) hash of a certificate. This is used 9 + # as description of keys in the blacklist keyring to identify certificates. 10 + # This output should be redirected, without newline, in a file (hash0.txt) and 11 + # signed to create a PKCS#7 file (hash0.p7s). Both of these files can then be 12 + # loaded in the kernel with. 13 + # 14 + # Exemple on a workstation: 15 + # ./print-cert-tbs-hash.sh certificate-to-invalidate.pem > hash0.txt 16 + # openssl smime -sign -in hash0.txt -inkey builtin-private-key.pem \ 17 + # -signer builtin-certificate.pem -certfile certificate-chain.pem \ 18 + # -noattr -binary -outform DER -out hash0.p7s 19 + # 20 + # Exemple on a managed system: 21 + # keyctl padd blacklist "$(< hash0.txt)" %:.blacklist < hash0.p7s 22 + 23 + set -u -e -o pipefail 24 + 25 + CERT="${1:-}" 26 + BASENAME="$(basename -- "${BASH_SOURCE[0]}")" 27 + 28 + if [ $# -ne 1 ] || [ ! -f "${CERT}" ]; then 29 + echo "usage: ${BASENAME} <certificate>" >&2 30 + exit 1 31 + fi 32 + 33 + # Checks that it is indeed a certificate (PEM or DER encoded) and exclude the 34 + # optional PEM text header. 35 + if ! PEM="$(openssl x509 -inform DER -in "${CERT}" 2>/dev/null || openssl x509 -in "${CERT}")"; then 36 + echo "ERROR: Failed to parse certificate" >&2 37 + exit 1 38 + fi 39 + 40 + # TBSCertificate starts at the second entry. 41 + # Cf. https://tools.ietf.org/html/rfc3280#section-4.1 42 + # 43 + # Exemple of first lines printed by openssl asn1parse: 44 + # 0:d=0 hl=4 l= 763 cons: SEQUENCE 45 + # 4:d=1 hl=4 l= 483 cons: SEQUENCE 46 + # 8:d=2 hl=2 l= 3 cons: cont [ 0 ] 47 + # 10:d=3 hl=2 l= 1 prim: INTEGER :02 48 + # 13:d=2 hl=2 l= 20 prim: INTEGER :3CEB2CB8818D968AC00EEFE195F0DF9665328B7B 49 + # 35:d=2 hl=2 l= 13 cons: SEQUENCE 50 + # 37:d=3 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption 51 + RANGE_AND_DIGEST_RE=' 52 + 2s/^\s*\([0-9]\+\):d=\s*[0-9]\+\s\+hl=\s*[0-9]\+\s\+l=\s*\([0-9]\+\)\s\+cons:\s*SEQUENCE\s*$/\1 \2/p; 53 + 7s/^\s*[0-9]\+:d=\s*[0-9]\+\s\+hl=\s*[0-9]\+\s\+l=\s*[0-9]\+\s\+prim:\s*OBJECT\s*:\(.*\)$/\1/p; 54 + ' 55 + 56 + RANGE_AND_DIGEST=($(echo "${PEM}" | \ 57 + openssl asn1parse -in - | \ 58 + sed -n -e "${RANGE_AND_DIGEST_RE}")) 59 + 60 + if [ "${#RANGE_AND_DIGEST[@]}" != 3 ]; then 61 + echo "ERROR: Failed to parse TBSCertificate." >&2 62 + exit 1 63 + fi 64 + 65 + OFFSET="${RANGE_AND_DIGEST[0]}" 66 + END="$(( OFFSET + RANGE_AND_DIGEST[1] ))" 67 + DIGEST="${RANGE_AND_DIGEST[2]}" 68 + 69 + # The signature hash algorithm is used by Linux to blacklist certificates. 70 + # Cf. crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo() 71 + DIGEST_MATCH="" 72 + while read -r DIGEST_ITEM; do 73 + if [ -z "${DIGEST_ITEM}" ]; then 74 + break 75 + fi 76 + if echo "${DIGEST}" | grep -qiF "${DIGEST_ITEM}"; then 77 + DIGEST_MATCH="${DIGEST_ITEM}" 78 + break 79 + fi 80 + done < <(openssl list -digest-commands | tr ' ' '\n' | sort -ur) 81 + 82 + if [ -z "${DIGEST_MATCH}" ]; then 83 + echo "ERROR: Unknown digest algorithm: ${DIGEST}" >&2 84 + exit 1 85 + fi 86 + 87 + echo "${PEM}" | \ 88 + openssl x509 -in - -outform DER | \ 89 + dd "bs=1" "skip=${OFFSET}" "count=${END}" "status=none" | \ 90 + openssl dgst "-${DIGEST_MATCH}" - | \ 91 + awk '{printf "tbs:" $2}'