Add support for portable EVM format
Add a --portable argument that generates EVM signatures without using the inode number and generation or fs UUID. Signed-off-by: Matthew Garrett <mjg59@google.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Changelog: - immutable and portable flags are exclusive, prevent enabling both.
This commit is contained in:
		
							
								
								
									
										6
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								README
									
									
									
									
									
								
							| @@ -26,7 +26,7 @@ COMMANDS | |||||||
|  --version |  --version | ||||||
|  help <command> |  help <command> | ||||||
|  import [--rsa] pubkey keyring |  import [--rsa] pubkey keyring | ||||||
|  sign [-r] [--imahash | --imasig ] [--key key] [--pass password] file |  sign [-r] [--imahash | --imasig ] [--portable] [--key key] [--pass password] file | ||||||
|  verify file |  verify file | ||||||
|  ima_sign [--sigfile] [--key key] [--pass password] file |  ima_sign [--sigfile] [--key key] [--pass password] file | ||||||
|  ima_verify file |  ima_verify file | ||||||
| @@ -46,6 +46,7 @@ OPTIONS | |||||||
|   -f, --sigfile      store IMA signature in .sig file instead of xattr |   -f, --sigfile      store IMA signature in .sig file instead of xattr | ||||||
|       --rsa          use RSA key type and signing scheme v1 |       --rsa          use RSA key type and signing scheme v1 | ||||||
|   -k, --key          path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem) |   -k, --key          path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem) | ||||||
|  |   -o, --portable     generate portable EVM signatures | ||||||
|   -p, --pass         password for encrypted signing key |   -p, --pass         password for encrypted signing key | ||||||
|   -r, --recursive    recurse into directories (sign) |   -r, --recursive    recurse into directories (sign) | ||||||
|   -t, --type         file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink) |   -t, --type         file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink) | ||||||
| @@ -95,7 +96,8 @@ Kernel configuration option CONFIG_EVM_ATTR_FSUUID controls whether to include | |||||||
| filesystem UUID into HMAC and enabled by default. Therefore evmctl also includes | filesystem UUID into HMAC and enabled by default. Therefore evmctl also includes | ||||||
| fsuuid by default. Providing '--uuid' option without parameter allows to disable | fsuuid by default. Providing '--uuid' option without parameter allows to disable | ||||||
| usage of fs uuid. Providing '--uuid=UUID' option with parameter allows to use | usage of fs uuid. Providing '--uuid=UUID' option with parameter allows to use | ||||||
| custom UUID. | custom UUID. Providing the '--portable' option will disable usage of the fs uuid | ||||||
|  | and also the inode number and generation. | ||||||
|  |  | ||||||
| Kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS controls whether to | Kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS controls whether to | ||||||
| include additional SMACK extended attributes into HMAC. They are following: | include additional SMACK extended attributes into HMAC. They are following: | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								src/evmctl.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/evmctl.c
									
									
									
									
									
								
							| @@ -117,6 +117,7 @@ static int recursive; | |||||||
| static int msize; | static int msize; | ||||||
| static dev_t fs_dev; | static dev_t fs_dev; | ||||||
| static bool evm_immutable; | static bool evm_immutable; | ||||||
|  | static bool evm_portable; | ||||||
|  |  | ||||||
| #define HMAC_FLAG_NO_UUID	0x0001 | #define HMAC_FLAG_NO_UUID	0x0001 | ||||||
| #define HMAC_FLAG_CAPS_SET	0x0002 | #define HMAC_FLAG_CAPS_SET	0x0002 | ||||||
| @@ -418,8 +419,10 @@ static int calc_evm_hash(const char *file, unsigned char *hash) | |||||||
| 		struct h_misc *hmac = (struct h_misc *)&hmac_misc; | 		struct h_misc *hmac = (struct h_misc *)&hmac_misc; | ||||||
|  |  | ||||||
| 		hmac_size = sizeof(*hmac); | 		hmac_size = sizeof(*hmac); | ||||||
|  | 		if (!evm_portable) { | ||||||
| 			hmac->ino = st.st_ino; | 			hmac->ino = st.st_ino; | ||||||
| 			hmac->generation = generation; | 			hmac->generation = generation; | ||||||
|  | 		} | ||||||
| 		hmac->uid = st.st_uid; | 		hmac->uid = st.st_uid; | ||||||
| 		hmac->gid = st.st_gid; | 		hmac->gid = st.st_gid; | ||||||
| 		hmac->mode = st.st_mode; | 		hmac->mode = st.st_mode; | ||||||
| @@ -427,8 +430,10 @@ static int calc_evm_hash(const char *file, unsigned char *hash) | |||||||
| 		struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc; | 		struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc; | ||||||
|  |  | ||||||
| 		hmac_size = sizeof(*hmac); | 		hmac_size = sizeof(*hmac); | ||||||
|  | 		if (!evm_portable) { | ||||||
| 			hmac->ino = st.st_ino; | 			hmac->ino = st.st_ino; | ||||||
| 			hmac->generation = generation; | 			hmac->generation = generation; | ||||||
|  | 		} | ||||||
| 		hmac->uid = st.st_uid; | 		hmac->uid = st.st_uid; | ||||||
| 		hmac->gid = st.st_gid; | 		hmac->gid = st.st_gid; | ||||||
| 		hmac->mode = st.st_mode; | 		hmac->mode = st.st_mode; | ||||||
| @@ -436,8 +441,10 @@ static int calc_evm_hash(const char *file, unsigned char *hash) | |||||||
| 		struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc; | 		struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc; | ||||||
|  |  | ||||||
| 		hmac_size = sizeof(*hmac); | 		hmac_size = sizeof(*hmac); | ||||||
|  | 		if (!evm_portable) { | ||||||
| 			hmac->ino = st.st_ino; | 			hmac->ino = st.st_ino; | ||||||
| 			hmac->generation = generation; | 			hmac->generation = generation; | ||||||
|  | 		} | ||||||
| 		hmac->uid = st.st_uid; | 		hmac->uid = st.st_uid; | ||||||
| 		hmac->gid = st.st_gid; | 		hmac->gid = st.st_gid; | ||||||
| 		hmac->mode = st.st_mode; | 		hmac->mode = st.st_mode; | ||||||
| @@ -452,7 +459,8 @@ static int calc_evm_hash(const char *file, unsigned char *hash) | |||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!evm_immutable && !(hmac_flags & HMAC_FLAG_NO_UUID)) { | 	if (!evm_immutable && !evm_portable && | ||||||
|  | 	    !(hmac_flags & HMAC_FLAG_NO_UUID)) { | ||||||
| 		err = get_uuid(&st, uuid); | 		err = get_uuid(&st, uuid); | ||||||
| 		if (err) | 		if (err) | ||||||
| 			return -1; | 			return -1; | ||||||
| @@ -489,6 +497,9 @@ static int sign_evm(const char *file, const char *key) | |||||||
|  |  | ||||||
| 	/* add header */ | 	/* add header */ | ||||||
| 	len++; | 	len++; | ||||||
|  | 	if (evm_portable) | ||||||
|  | 		sig[0] = EVM_XATTR_PORTABLE_DIGSIG; | ||||||
|  | 	else | ||||||
| 		sig[0] = EVM_IMA_XATTR_DIGSIG; | 		sig[0] = EVM_IMA_XATTR_DIGSIG; | ||||||
|  |  | ||||||
| 	if (evm_immutable) | 	if (evm_immutable) | ||||||
| @@ -1552,6 +1563,7 @@ static void usage(void) | |||||||
| 		"  -f, --sigfile      store IMA signature in .sig file instead of xattr\n" | 		"  -f, --sigfile      store IMA signature in .sig file instead of xattr\n" | ||||||
| 		"      --rsa          use RSA key type and signing scheme v1\n" | 		"      --rsa          use RSA key type and signing scheme v1\n" | ||||||
| 		"  -k, --key          path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)\n" | 		"  -k, --key          path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)\n" | ||||||
|  | 		"  -o, --portable     generate portable EVM signatures\n" | ||||||
| 		"  -p, --pass         password for encrypted signing key\n" | 		"  -p, --pass         password for encrypted signing key\n" | ||||||
| 		"  -r, --recursive    recurse into directories (sign)\n" | 		"  -r, --recursive    recurse into directories (sign)\n" | ||||||
| 		"  -t, --type         file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)\n" | 		"  -t, --type         file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)\n" | ||||||
| @@ -1610,6 +1622,7 @@ static struct option opts[] = { | |||||||
| 	{"recursive", 0, 0, 'r'}, | 	{"recursive", 0, 0, 'r'}, | ||||||
| 	{"m32", 0, 0, '3'}, | 	{"m32", 0, 0, '3'}, | ||||||
| 	{"m64", 0, 0, '6'}, | 	{"m64", 0, 0, '6'}, | ||||||
|  | 	{"portable", 0, 0, 'o'}, | ||||||
| 	{"smack", 0, 0, 128}, | 	{"smack", 0, 0, 128}, | ||||||
| 	{"version", 0, 0, 129}, | 	{"version", 0, 0, 129}, | ||||||
| 	{"inode", 1, 0, 130}, | 	{"inode", 1, 0, 130}, | ||||||
| @@ -1666,7 +1679,7 @@ int main(int argc, char *argv[]) | |||||||
| 	g_argc = argc; | 	g_argc = argc; | ||||||
|  |  | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		c = getopt_long(argc, argv, "hvnsda:p::fu::k:t:ri", opts, &lind); | 		c = getopt_long(argc, argv, "hvnsda:op::fu::k:t:ri", opts, &lind); | ||||||
| 		if (c == -1) | 		if (c == -1) | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -1713,8 +1726,17 @@ int main(int argc, char *argv[]) | |||||||
| 			params.keyfile = optarg; | 			params.keyfile = optarg; | ||||||
| 			break; | 			break; | ||||||
| 		case 'i': | 		case 'i': | ||||||
|  | 			if (evm_portable) | ||||||
|  | 				log_err("Portable and immutable options are exclusive, ignoring immutable option."); | ||||||
|  | 			else | ||||||
| 				evm_immutable = true; | 				evm_immutable = true; | ||||||
| 			break; | 			break; | ||||||
|  | 		case 'o': | ||||||
|  | 			if (evm_immutable) | ||||||
|  | 				log_err("Portable and immutable options are exclusive, ignoring portable option."); | ||||||
|  | 			else | ||||||
|  | 				evm_portable = true; | ||||||
|  | 			break; | ||||||
| 		case 't': | 		case 't': | ||||||
| 			search_type = optarg; | 			search_type = optarg; | ||||||
| 			break; | 			break; | ||||||
|   | |||||||
| @@ -82,6 +82,7 @@ enum evm_ima_xattr_type { | |||||||
| 	EVM_XATTR_HMAC, | 	EVM_XATTR_HMAC, | ||||||
| 	EVM_IMA_XATTR_DIGSIG, | 	EVM_IMA_XATTR_DIGSIG, | ||||||
| 	IMA_XATTR_DIGEST_NG, | 	IMA_XATTR_DIGEST_NG, | ||||||
|  | 	EVM_XATTR_PORTABLE_DIGSIG, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct h_misc { | struct h_misc { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Matthew Garrett
					Matthew Garrett