It is possible that one uses external cryptographic engine to create
RSA PKCS1.5 signature of a file. Import these signatures and wrap it with
IMA specific metadata to convert it into IMA signature.

For example, one could do following.

$ echo "Hello World" > /tmp/data.txt
$ openssl dgst -sha256 -sign signing_key.priv.pem -out /tmp/data.sig 
/tmp/data.txt
$ evmctl ima_sig_import -x -a sha256 -k signing_key.x509.der /tmp/data.sig 
/tmp/data.txt

# Verify  signature
$ evmctl ima_verify -k signing_key.x509.der /tmp/data.txt

Signed-off-by: Vivek Goyal <[email protected]>
---
 src/evmctl.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/src/evmctl.c b/src/evmctl.c
index e24b9ed..3679e68 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1133,6 +1133,89 @@ static int cmd_sign_evm(struct command *cmd)
        return sign_evm(file, key);
 }
 
+static int ima_sig_import_v2(const char *hashalgo, const char *keyfile, const 
char *rawsigfile, const char *file)
+{
+       unsigned char *rawsig;
+       int rawsigsz, len, ret = 0, memlock_len;
+       unsigned char sig[1024] = "\x03";
+       char name[20];
+       struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)(sig + 1);
+       RSA *key;
+
+       rawsig = file2bin(rawsigfile, NULL, &rawsigsz);
+       if (!rawsig) {
+               log_err("Unable to read file %s\n", rawsigfile);
+               return 1;
+       }
+
+       key = read_pub_key(keyfile);
+       if (!key) {
+               free(rawsig);
+               return 1;
+       }
+
+       hdr->version = 2;
+       hdr->hash_algo = get_hash_algo(hashalgo);
+
+       calc_keyid_v2(&hdr->keyid, name, key);
+       memcpy(hdr->sig, rawsig, rawsigsz);
+
+       len = rawsigsz;
+       hdr->sig_size = __cpu_to_be16(len);
+       len += sizeof(*hdr);
+       log_info("evm/ima signature: %d bytes\n", len);
+       if (sigdump || verbose >= LOG_INFO)
+               dump(sig + 1, len);
+
+       /* Add ima header */
+       len++;
+       if (memlock) {
+               memlock_len = add_memlock_info(sig + len);
+               len += memlock_len;
+       }
+
+       if (sigfile)
+               bin2file(file, "sig", sig, len);
+
+       if (xattr) {
+               ret = setxattr(file, "security.ima", sig, len, 0);
+               if (ret < 0) {
+                       log_err("setxattr failed: %s\n", file);
+                       goto out;
+               }
+       }
+
+out:
+       RSA_free(key);
+       free(rawsig);
+       return ret;
+}
+
+static int cmd_ima_sig_import(struct command *cmd)
+{
+       char *rawsigfile, *file, *key;
+
+       rawsigfile = g_argv[optind++];
+       file = g_argv[optind++];
+
+       if (!file || !rawsigfile) {
+               log_err("Parameters missing\n");
+               print_usage(cmd);
+               return -1;
+       }
+
+       key = keyfile ? : x509 ?
+                       "/etc/keys/x509_evm.der" :
+                       "/etc/keys/pubkey_evm.pem";
+
+       if (x509)
+               return ima_sig_import_v2(hash_algo, key, rawsigfile, file);
+       else {
+               log_err("Signature version 1 import not supported.\n");
+               return 1;
+       }
+}
+
 static int verify_hash_v1(const unsigned char *hash, int size, unsigned char 
*sig, int siglen, const char *keyfile)
 {
        int err, len;
@@ -1694,6 +1777,7 @@ struct command cmds[] = {
 #ifdef DEBUG
        {"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig ] file", "Sign file 
metadata with HMAC using symmetric key (for testing purpose).\n"},
 #endif
+       {"ima_sig_import", cmd_ima_sig_import, 0, "[--x509] [-a hashalgo] [-k 
pubkey] signature file", "Make IMA signature from externally signed raw 
signature blob.\n"},
        {0, 0, 0, NULL}
 };
 
-- 
1.8.3.1

_______________________________________________
kernel mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/kernel

Reply via email to