* [ima-evm-utils PATCH 01/12] Rename "public_keys" to "g_public_keys"
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 12:44 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 02/12] Free public keys list Mimi Zohar
` (10 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
In preparation for replacing the library global public_keys variable,
which is not concurrency-safe, with a local variable, rename public_keys
to g_public_keys.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/libimaevm.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 5b224625644e..117a1a72b60c 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -370,14 +370,14 @@ struct public_key_entry {
char name[9];
EVP_PKEY *key;
};
-static struct public_key_entry *public_keys = NULL;
+static struct public_key_entry *g_public_keys = NULL;
static EVP_PKEY *find_keyid(uint32_t keyid)
{
- struct public_key_entry *entry, *tail = public_keys;
+ struct public_key_entry *entry, *tail = g_public_keys;
int i = 1;
- for (entry = public_keys; entry != NULL; entry = entry->next) {
+ for (entry = g_public_keys; entry != NULL; entry = entry->next) {
if (entry->keyid == keyid)
return entry->key;
i++;
@@ -394,7 +394,7 @@ static EVP_PKEY *find_keyid(uint32_t keyid)
if (tail)
tail->next = entry;
else
- public_keys = entry;
+ g_public_keys = entry;
log_err("key %d: %x (unknown keyid)\n", i, __be32_to_cpup(&keyid));
return 0;
}
@@ -429,8 +429,8 @@ void init_public_keys(const char *keyfiles)
calc_keyid_v2(&entry->keyid, entry->name, entry->key);
sprintf(entry->name, "%x", __be32_to_cpup(&entry->keyid));
log_info("key %d: %s %s\n", i++, entry->name, keyfile);
- entry->next = public_keys;
- public_keys = entry;
+ entry->next = g_public_keys;
+ g_public_keys = entry;
}
free(keyfiles_free);
}
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 01/12] Rename "public_keys" to "g_public_keys"
2023-11-19 16:50 ` [ima-evm-utils PATCH 01/12] Rename "public_keys" to "g_public_keys" Mimi Zohar
@ 2023-11-22 12:44 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 12:44 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> In preparation for replacing the library global public_keys variable,
> which is not concurrency-safe, with a local variable, rename public_keys
> to g_public_keys.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> ---
> src/libimaevm.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index 5b224625644e..117a1a72b60c 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -370,14 +370,14 @@ struct public_key_entry {
> char name[9];
> EVP_PKEY *key;
> };
> -static struct public_key_entry *public_keys = NULL;
> +static struct public_key_entry *g_public_keys = NULL;
>
> static EVP_PKEY *find_keyid(uint32_t keyid)
> {
> - struct public_key_entry *entry, *tail = public_keys;
> + struct public_key_entry *entry, *tail = g_public_keys;
> int i = 1;
>
> - for (entry = public_keys; entry != NULL; entry = entry->next) {
> + for (entry = g_public_keys; entry != NULL; entry = entry->next) {
> if (entry->keyid == keyid)
> return entry->key;
> i++;
> @@ -394,7 +394,7 @@ static EVP_PKEY *find_keyid(uint32_t keyid)
> if (tail)
> tail->next = entry;
> else
> - public_keys = entry;
> + g_public_keys = entry;
> log_err("key %d: %x (unknown keyid)\n", i, __be32_to_cpup(&keyid));
> return 0;
> }
> @@ -429,8 +429,8 @@ void init_public_keys(const char *keyfiles)
> calc_keyid_v2(&entry->keyid, entry->name, entry->key);
> sprintf(entry->name, "%x", __be32_to_cpup(&entry->keyid));
> log_info("key %d: %s %s\n", i++, entry->name, keyfile);
> - entry->next = public_keys;
> - public_keys = entry;
> + entry->next = g_public_keys;
> + g_public_keys = entry;
> }
> free(keyfiles_free);
> }
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 02/12] Free public keys list
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
2023-11-19 16:50 ` [ima-evm-utils PATCH 01/12] Rename "public_keys" to "g_public_keys" Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 12:52 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 03/12] Update library function definitions to include a "public_keys" parameter Mimi Zohar
` (9 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
On failure to allocate memory, free the public keys list.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/imaevm.h | 1 +
src/libimaevm.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/src/imaevm.h b/src/imaevm.h
index 18d7b0e447e1..828976e52881 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -249,6 +249,7 @@ uint32_t imaevm_read_keyid(const char *certfile);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
+void free_public_keys(void *public_keys);
void init_public_keys(const char *keyfiles);
int imaevm_hash_algo_from_sig(unsigned char *sig);
const char *imaevm_hash_algo_by_id(int algo);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 117a1a72b60c..74e9d09b1f05 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -399,11 +399,25 @@ static EVP_PKEY *find_keyid(uint32_t keyid)
return 0;
}
+void free_public_keys(void *public_keys)
+{
+ struct public_key_entry *entry = public_keys, *next;
+
+ while (entry != NULL) {
+ next = entry->next;
+ if (entry->key)
+ free(entry->key);
+ free(entry);
+ entry = next;
+ }
+}
+
void init_public_keys(const char *keyfiles)
{
struct public_key_entry *entry;
char *tmp_keyfiles, *keyfiles_free;
char *keyfile;
+ int err = 0;
int i = 1;
tmp_keyfiles = strdup(keyfiles);
@@ -417,6 +431,7 @@ void init_public_keys(const char *keyfiles)
entry = malloc(sizeof(struct public_key_entry));
if (!entry) {
perror("malloc");
+ err = -ENOMEM;
break;
}
@@ -433,6 +448,8 @@ void init_public_keys(const char *keyfiles)
g_public_keys = entry;
}
free(keyfiles_free);
+ if (err < 0)
+ free_public_keys(g_public_keys);
}
/*
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 02/12] Free public keys list
2023-11-19 16:50 ` [ima-evm-utils PATCH 02/12] Free public keys list Mimi Zohar
@ 2023-11-22 12:52 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 12:52 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> On failure to allocate memory, free the public keys list.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/imaevm.h | 1 +
> src/libimaevm.c | 17 +++++++++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/src/imaevm.h b/src/imaevm.h
> index 18d7b0e447e1..828976e52881 100644
> --- a/src/imaevm.h
> +++ b/src/imaevm.h
> @@ -249,6 +249,7 @@ uint32_t imaevm_read_keyid(const char *certfile);
> int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
> int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
> int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
> +void free_public_keys(void *public_keys);
> void init_public_keys(const char *keyfiles);
> int imaevm_hash_algo_from_sig(unsigned char *sig);
> const char *imaevm_hash_algo_by_id(int algo);
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index 117a1a72b60c..74e9d09b1f05 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -399,11 +399,25 @@ static EVP_PKEY *find_keyid(uint32_t keyid)
> return 0;
> }
>
> +void free_public_keys(void *public_keys)
> +{
> + struct public_key_entry *entry = public_keys, *next;
> +
> + while (entry != NULL) {
> + next = entry->next;
> + if (entry->key)
> + free(entry->key);
> + free(entry);
> + entry = next;
> + }
> +}
> +
> void init_public_keys(const char *keyfiles)
> {
> struct public_key_entry *entry;
> char *tmp_keyfiles, *keyfiles_free;
> char *keyfile;
> + int err = 0;
> int i = 1;
>
> tmp_keyfiles = strdup(keyfiles);
> @@ -417,6 +431,7 @@ void init_public_keys(const char *keyfiles)
> entry = malloc(sizeof(struct public_key_entry));
> if (!entry) {
> perror("malloc");
> + err = -ENOMEM;
> break;
> }
>
> @@ -433,6 +448,8 @@ void init_public_keys(const char *keyfiles)
> g_public_keys = entry;
> }
> free(keyfiles_free);
> + if (err < 0)
> + free_public_keys(g_public_keys);
> }
>
> /*
Unfortunately you cannot return the err to callers...
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 03/12] Update library function definitions to include a "public_keys" parameter
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
2023-11-19 16:50 ` [ima-evm-utils PATCH 01/12] Rename "public_keys" to "g_public_keys" Mimi Zohar
2023-11-19 16:50 ` [ima-evm-utils PATCH 02/12] Free public keys list Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:07 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 04/12] Update a library function definition to include a "hash_algo" parameter Mimi Zohar
` (8 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on a global static "public_keys" variable, which is
not concurrency-safe, update static library function definitions to
include it as a parameter, define new library functions with it as
a parameter, and deprecate existing functions.
Define init_public_keys2(), verify_hash2(), and ima_verify_signature2()
functions. Update static function defintions to include "public_keys".
To avoid library incompatablity, make the existing functions -
init_public_keys(), verify_hash(), ima_verify_signature() - wrappers
for the new function versions.
Deprecate init_public_keys(), verify_hash(), ima_verify_signature()
functions.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/imaevm.h | 2 ++
src/libimaevm.c | 94 +++++++++++++++++++++++++++++++++++++------------
2 files changed, 74 insertions(+), 22 deletions(-)
diff --git a/src/imaevm.h b/src/imaevm.h
index 828976e52881..146123ba5c42 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -249,8 +249,10 @@ uint32_t imaevm_read_keyid(const char *certfile);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
+int ima_verify_signature2(void *public_keys, const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
void free_public_keys(void *public_keys);
void init_public_keys(const char *keyfiles);
+int init_public_keys2(const char *keyfiles, void **public_keys);
int imaevm_hash_algo_from_sig(unsigned char *sig);
const char *imaevm_hash_algo_by_id(int algo);
int calc_hash_sigv3(enum evm_ima_xattr_type type, const char *algo, const unsigned char *in_hash, unsigned char *out_hash);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 74e9d09b1f05..bf8c99770ddc 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -372,12 +372,12 @@ struct public_key_entry {
};
static struct public_key_entry *g_public_keys = NULL;
-static EVP_PKEY *find_keyid(uint32_t keyid)
+static EVP_PKEY *find_keyid(void *public_keys, uint32_t keyid)
{
- struct public_key_entry *entry, *tail = g_public_keys;
+ struct public_key_entry *entry, *tail = public_keys;
int i = 1;
- for (entry = g_public_keys; entry != NULL; entry = entry->next) {
+ for (entry = public_keys; entry != NULL; entry = entry->next) {
if (entry->keyid == keyid)
return entry->key;
i++;
@@ -394,7 +394,7 @@ static EVP_PKEY *find_keyid(uint32_t keyid)
if (tail)
tail->next = entry;
else
- g_public_keys = entry;
+ public_keys = (void *) entry;
log_err("key %d: %x (unknown keyid)\n", i, __be32_to_cpup(&keyid));
return 0;
}
@@ -412,7 +412,7 @@ void free_public_keys(void *public_keys)
}
}
-void init_public_keys(const char *keyfiles)
+int init_public_keys2(const char *keyfiles, void **public_keys)
{
struct public_key_entry *entry;
char *tmp_keyfiles, *keyfiles_free;
@@ -420,6 +420,11 @@ void init_public_keys(const char *keyfiles)
int err = 0;
int i = 1;
+ if (!public_keys)
+ return -EINVAL;
+
+ *public_keys = NULL;
+
tmp_keyfiles = strdup(keyfiles);
keyfiles_free = tmp_keyfiles;
@@ -444,12 +449,24 @@ void init_public_keys(const char *keyfiles)
calc_keyid_v2(&entry->keyid, entry->name, entry->key);
sprintf(entry->name, "%x", __be32_to_cpup(&entry->keyid));
log_info("key %d: %s %s\n", i++, entry->name, keyfile);
- entry->next = g_public_keys;
- g_public_keys = entry;
+ entry->next = (struct public_key_entry *) *public_keys;
+ *public_keys = (void *)entry;
}
+
free(keyfiles_free);
if (err < 0)
- free_public_keys(g_public_keys);
+ free_public_keys(public_keys);
+ return err;
+}
+
+/*
+ * Global static variables are not concurrency-safe.
+ *
+ * Deprecate init_public_keys() usage.
+ */
+void init_public_keys(const char *keyfiles)
+{
+ init_public_keys2(keyfiles, (void **)&g_public_keys);
}
/*
@@ -466,7 +483,8 @@ void init_public_keys(const char *keyfiles)
*
* (Note: signature_v2_hdr struct does not contain the 'type'.)
*/
-static int verify_hash_common(const char *file, const unsigned char *hash,
+static int verify_hash_common(void *public_keys, const char *file,
+ const unsigned char *hash,
int size, unsigned char *sig, int siglen)
{
int ret = -1;
@@ -481,7 +499,7 @@ static int verify_hash_common(const char *file, const unsigned char *hash,
log_dump(hash, size);
}
- pkey = find_keyid(hdr->keyid);
+ pkey = find_keyid(public_keys, hdr->keyid);
if (!pkey) {
uint32_t keyid = hdr->keyid;
@@ -543,11 +561,13 @@ err:
*
* Return: 0 verification good, 1 verification bad, -1 error.
*/
-static int verify_hash_v2(const char *file, const unsigned char *hash,
+static int verify_hash_v2(void *public_keys, const char *file,
+ const unsigned char *hash,
int size, unsigned char *sig, int siglen)
{
/* note: signature_v2_hdr does not contain 'type', use sig + 1 */
- return verify_hash_common(file, hash, size, sig + 1, siglen - 1);
+ return verify_hash_common(public_keys, file, hash, size,
+ sig + 1, siglen - 1);
}
/*
@@ -556,7 +576,8 @@ static int verify_hash_v2(const char *file, const unsigned char *hash,
*
* Return: 0 verification good, 1 verification bad, -1 error.
*/
-static int verify_hash_v3(const char *file, const unsigned char *hash,
+static int verify_hash_v3(void *public_keys, const char *file,
+ const unsigned char *hash,
int size, unsigned char *sig, int siglen)
{
unsigned char sigv3_hash[MAX_DIGEST_SIZE];
@@ -567,7 +588,8 @@ static int verify_hash_v3(const char *file, const unsigned char *hash,
return ret;
/* note: signature_v2_hdr does not contain 'type', use sig + 1 */
- return verify_hash_common(file, sigv3_hash, size, sig + 1, siglen - 1);
+ return verify_hash_common(public_keys, file, sigv3_hash, size,
+ sig + 1, siglen - 1);
}
#define HASH_MAX_DIGESTSIZE 64 /* kernel HASH_MAX_DIGESTSIZE is 64 bytes */
@@ -710,8 +732,9 @@ int imaevm_hash_algo_from_sig(unsigned char *sig)
return -1;
}
-int verify_hash(const char *file, const unsigned char *hash, int size,
- unsigned char *sig, int siglen)
+int verify_hash2(void *public_keys, const char *file,
+ const unsigned char *hash, int size,
+ unsigned char *sig, int siglen)
{
/* Get signature type from sig header */
if (sig[1] == DIGSIG_VERSION_1) {
@@ -730,15 +753,29 @@ int verify_hash(const char *file, const unsigned char *hash, int size,
return -1;
#endif
} else if (sig[1] == DIGSIG_VERSION_2) {
- return verify_hash_v2(file, hash, size, sig, siglen);
+ return verify_hash_v2(public_keys, file, hash, size,
+ sig, siglen);
} else if (sig[1] == DIGSIG_VERSION_3) {
- return verify_hash_v3(file, hash, size, sig, siglen);
+ return verify_hash_v3(public_keys, file, hash, size,
+ sig, siglen);
} else
return -1;
}
-int ima_verify_signature(const char *file, unsigned char *sig, int siglen,
- unsigned char *digest, int digestlen)
+/*
+ * Global static variables are not concurrency-safe.
+ *
+ * Deprecate verify_hash() usage.
+ */
+int verify_hash(const char *file, const unsigned char *hash, int size,
+ unsigned char *sig, int siglen)
+{
+ return verify_hash2(g_public_keys, file, hash, size, sig, siglen);
+}
+
+int ima_verify_signature2(void *public_keys, const char *file,
+ unsigned char *sig, int siglen,
+ unsigned char *digest, int digestlen)
{
unsigned char hash[MAX_DIGEST_SIZE];
int hashlen, sig_hash_algo;
@@ -766,14 +803,27 @@ int ima_verify_signature(const char *file, unsigned char *sig, int siglen,
* measurement list, not by calculating the local file digest.
*/
if (digest && digestlen > 0)
- return verify_hash(file, digest, digestlen, sig, siglen);
+ return verify_hash2(public_keys, file, digest, digestlen,
+ sig, siglen);
hashlen = ima_calc_hash(file, hash);
if (hashlen <= 1)
return hashlen;
assert(hashlen <= sizeof(hash));
- return verify_hash(file, hash, hashlen, sig, siglen);
+ return verify_hash2(public_keys, file, hash, hashlen, sig, siglen);
+}
+
+/*
+ * Global static variables are not concurrency-safe.
+ *
+ * Deprecate ima_verify_signature() usage.
+ */
+int ima_verify_signature(const char *file, unsigned char *sig, int siglen,
+ unsigned char *digest, int digestlen)
+{
+ return ima_verify_signature2(g_public_keys, file, sig, siglen,
+ digest, digestlen);
}
#if CONFIG_SIGV1
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 03/12] Update library function definitions to include a "public_keys" parameter
2023-11-19 16:50 ` [ima-evm-utils PATCH 03/12] Update library function definitions to include a "public_keys" parameter Mimi Zohar
@ 2023-11-22 13:07 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:07 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on a global static "public_keys" variable, which is
> not concurrency-safe, update static library function definitions to
> include it as a parameter, define new library functions with it as
> a parameter, and deprecate existing functions.
>
> Define init_public_keys2(), verify_hash2(), and ima_verify_signature2()
> functions. Update static function defintions to include "public_keys".
-> definitions
>
> To avoid library incompatablity, make the existing functions -
-> incompatibility
> init_public_keys(), verify_hash(), ima_verify_signature() - wrappers
> for the new function versions.
>
> Deprecate init_public_keys(), verify_hash(), ima_verify_signature()
> functions.
It may be worth considering adding __attribute__((deprecated)) to those
functions.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/imaevm.h | 2 ++
> src/libimaevm.c | 94 +++++++++++++++++++++++++++++++++++++------------
> 2 files changed, 74 insertions(+), 22 deletions(-)
>
> diff --git a/src/imaevm.h b/src/imaevm.h
> index 828976e52881..146123ba5c42 100644
> --- a/src/imaevm.h
> +++ b/src/imaevm.h
> @@ -249,8 +249,10 @@ uint32_t imaevm_read_keyid(const char *certfile);
> int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
> int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
> int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
> +int ima_verify_signature2(void *public_keys, const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
> void free_public_keys(void *public_keys);
> void init_public_keys(const char *keyfiles);
> +int init_public_keys2(const char *keyfiles, void **public_keys);
> int imaevm_hash_algo_from_sig(unsigned char *sig);
> const char *imaevm_hash_algo_by_id(int algo);
> int calc_hash_sigv3(enum evm_ima_xattr_type type, const char *algo, const unsigned char *in_hash, unsigned char *out_hash);
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index 74e9d09b1f05..bf8c99770ddc 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -372,12 +372,12 @@ struct public_key_entry {
> };
> static struct public_key_entry *g_public_keys = NULL;
>
> -static EVP_PKEY *find_keyid(uint32_t keyid)
> +static EVP_PKEY *find_keyid(void *public_keys, uint32_t keyid)
> {
> - struct public_key_entry *entry, *tail = g_public_keys;
> + struct public_key_entry *entry, *tail = public_keys;
> int i = 1;
>
> - for (entry = g_public_keys; entry != NULL; entry = entry->next) {
> + for (entry = public_keys; entry != NULL; entry = entry->next) {
> if (entry->keyid == keyid)
> return entry->key;
> i++;
> @@ -394,7 +394,7 @@ static EVP_PKEY *find_keyid(uint32_t keyid)
> if (tail)
> tail->next = entry;
> else
> - g_public_keys = entry;
> + public_keys = (void *) entry;
> log_err("key %d: %x (unknown keyid)\n", i, __be32_to_cpup(&keyid));
> return 0;
> }
> @@ -412,7 +412,7 @@ void free_public_keys(void *public_keys)
> }
> }
>
> -void init_public_keys(const char *keyfiles)
> +int init_public_keys2(const char *keyfiles, void **public_keys)
Even though callers of the public APIs may get void *, inside the
library this can be passed around with its concrete type.
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 04/12] Update a library function definition to include a "hash_algo" parameter
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (2 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 03/12] Update library function definitions to include a "public_keys" parameter Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:14 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 05/12] Update cmd_verify_ima() to define and use a local list of public keys Mimi Zohar
` (7 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on a global "hash_algo" variable, which is not
concurrency-safe, update the verify_hash2() function definition to
include a "hash_algo" parameter as a place holder.
Export the verify_hash2() definition.
Define verify_hash2(). To avoid library incompatablity, make the existing
function verify_hash() a function wrapper for verify_hash2().
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/imaevm.h | 1 +
src/libimaevm.c | 9 +++++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/imaevm.h b/src/imaevm.h
index 146123ba5c42..1ed2c81d510d 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -248,6 +248,7 @@ uint32_t imaevm_read_keyid(const char *certfile);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
+int verify_hash2(void *public_keys, const char *file, const char *hash_algo, const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
int ima_verify_signature2(void *public_keys, const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
void free_public_keys(void *public_keys);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index bf8c99770ddc..e64d167a2a8a 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -732,7 +732,7 @@ int imaevm_hash_algo_from_sig(unsigned char *sig)
return -1;
}
-int verify_hash2(void *public_keys, const char *file,
+int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
const unsigned char *hash, int size,
unsigned char *sig, int siglen)
{
@@ -770,7 +770,7 @@ int verify_hash2(void *public_keys, const char *file,
int verify_hash(const char *file, const unsigned char *hash, int size,
unsigned char *sig, int siglen)
{
- return verify_hash2(g_public_keys, file, hash, size, sig, siglen);
+ return verify_hash2(g_public_keys, file, NULL, hash, size, sig, siglen);
}
int ima_verify_signature2(void *public_keys, const char *file,
@@ -803,7 +803,7 @@ int ima_verify_signature2(void *public_keys, const char *file,
* measurement list, not by calculating the local file digest.
*/
if (digest && digestlen > 0)
- return verify_hash2(public_keys, file, digest, digestlen,
+ return verify_hash2(public_keys, file, NULL, digest, digestlen,
sig, siglen);
hashlen = ima_calc_hash(file, hash);
@@ -811,7 +811,8 @@ int ima_verify_signature2(void *public_keys, const char *file,
return hashlen;
assert(hashlen <= sizeof(hash));
- return verify_hash2(public_keys, file, hash, hashlen, sig, siglen);
+ return verify_hash2(public_keys, file, NULL, hash, hashlen,
+ sig, siglen);
}
/*
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 04/12] Update a library function definition to include a "hash_algo" parameter
2023-11-19 16:50 ` [ima-evm-utils PATCH 04/12] Update a library function definition to include a "hash_algo" parameter Mimi Zohar
@ 2023-11-22 13:14 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:14 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on a global "hash_algo" variable, which is not
> concurrency-safe, update the verify_hash2() function definition to
> include a "hash_algo" parameter as a place holder.
>
> Export the verify_hash2() definition.
>
> Define verify_hash2(). To avoid library incompatablity, make the existing
-> incompatibility
> function verify_hash() a function wrapper for verify_hash2().
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/imaevm.h | 1 +
> src/libimaevm.c | 9 +++++----
> 2 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/src/imaevm.h b/src/imaevm.h
> index 146123ba5c42..1ed2c81d510d 100644
> --- a/src/imaevm.h
> +++ b/src/imaevm.h
> @@ -248,6 +248,7 @@ uint32_t imaevm_read_keyid(const char *certfile);
>
> int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
> int verify_hash(const char *file, const unsigned char *hash, int size, unsigned char *sig, int siglen);
> +int verify_hash2(void *public_keys, const char *file, const char *hash_algo, const unsigned char *hash, int size, unsigned char *sig, int siglen);
> int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
> int ima_verify_signature2(void *public_keys, const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
> void free_public_keys(void *public_keys);
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index bf8c99770ddc..e64d167a2a8a 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -732,7 +732,7 @@ int imaevm_hash_algo_from_sig(unsigned char *sig)
> return -1;
> }
>
> -int verify_hash2(void *public_keys, const char *file,
> +int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
> const unsigned char *hash, int size,
> unsigned char *sig, int siglen)
> {
> @@ -770,7 +770,7 @@ int verify_hash2(void *public_keys, const char *file,
> int verify_hash(const char *file, const unsigned char *hash, int size,
> unsigned char *sig, int siglen)
> {
> - return verify_hash2(g_public_keys, file, hash, size, sig, siglen);
> + return verify_hash2(g_public_keys, file, NULL, hash, size, sig, siglen);
> }
>
> int ima_verify_signature2(void *public_keys, const char *file,
> @@ -803,7 +803,7 @@ int ima_verify_signature2(void *public_keys, const char *file,
> * measurement list, not by calculating the local file digest.
> */
> if (digest && digestlen > 0)
> - return verify_hash2(public_keys, file, digest, digestlen,
> + return verify_hash2(public_keys, file, NULL, digest, digestlen,
> sig, siglen);
>
> hashlen = ima_calc_hash(file, hash);
> @@ -811,7 +811,8 @@ int ima_verify_signature2(void *public_keys, const char *file,
> return hashlen;
> assert(hashlen <= sizeof(hash));
>
> - return verify_hash2(public_keys, file, hash, hashlen, sig, siglen);
> + return verify_hash2(public_keys, file, NULL, hash, hashlen,
> + sig, siglen);
> }
>
> /*
At this points verify_hash2 becomes a public function (by adding it to
imaevm.h) and it gets an additional parameter but the parameter is not
used at all...
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 05/12] Update cmd_verify_ima() to define and use a local list of public keys
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (3 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 04/12] Update a library function definition to include a "hash_algo" parameter Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:16 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 06/12] Update cmd_verify_evm " Mimi Zohar
` (6 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Update the static verify_ima() fucntion definition to include "public_keys".
Replace calling init_public_keys() with the init_public_keys2() version.
Similarly replace ima_verify_signature() with the ima_verify_signature2()
version.
Free the local public keys list.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/evmctl.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 4190913f0295..bf1f8f07e9ca 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -972,7 +972,7 @@ static int cmd_verify_evm(struct command *cmd)
return err;
}
-static int verify_ima(const char *file)
+static int verify_ima(void *public_keys, const char *file)
{
unsigned char sig[MAX_SIGNATURE_SIZE];
int len;
@@ -999,34 +999,37 @@ static int verify_ima(const char *file)
}
}
- return ima_verify_signature(file, sig, len, NULL, 0);
+ return ima_verify_signature2(public_keys, file, sig, len, NULL, 0);
}
static int cmd_verify_ima(struct command *cmd)
{
char *file = g_argv[optind++];
+ void *public_keys = NULL;
int err, fails = 0;
- if (imaevm_params.x509) {
- if (imaevm_params.keyfile) /* Support multiple public keys */
- init_public_keys(imaevm_params.keyfile);
- else /* assume read pubkey from x509 cert */
- init_public_keys("/etc/keys/x509_evm.der");
- }
-
if (!file) {
log_err("Parameters missing\n");
print_usage(cmd);
return -1;
}
+ if (imaevm_params.x509) {
+ if (imaevm_params.keyfile) /* Support multiple public keys */
+ init_public_keys2(imaevm_params.keyfile, &public_keys);
+ else /* assume read pubkey from x509 cert */
+ init_public_keys2("/etc/keys/x509_evm.der", &public_keys);
+ }
+
do {
- err = verify_ima(file);
+ err = verify_ima(public_keys, file);
if (err)
fails++;
if (!err && imaevm_params.verbose >= LOG_INFO)
log_info("%s: verification is OK\n", file);
} while ((file = g_argv[optind++]));
+
+ free_public_keys(public_keys);
return fails > 0;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 05/12] Update cmd_verify_ima() to define and use a local list of public keys
2023-11-19 16:50 ` [ima-evm-utils PATCH 05/12] Update cmd_verify_ima() to define and use a local list of public keys Mimi Zohar
@ 2023-11-22 13:16 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:16 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Update the static verify_ima() fucntion definition to include "public_keys".
>
-> function
> Replace calling init_public_keys() with the init_public_keys2() version.
> Similarly replace ima_verify_signature() with the ima_verify_signature2()
> version.
>
> Free the local public keys list.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/evmctl.c | 23 +++++++++++++----------
> 1 file changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/src/evmctl.c b/src/evmctl.c
> index 4190913f0295..bf1f8f07e9ca 100644
> --- a/src/evmctl.c
> +++ b/src/evmctl.c
> @@ -972,7 +972,7 @@ static int cmd_verify_evm(struct command *cmd)
> return err;
> }
>
> -static int verify_ima(const char *file)
> +static int verify_ima(void *public_keys, const char *file)
> {
> unsigned char sig[MAX_SIGNATURE_SIZE];
> int len;
> @@ -999,34 +999,37 @@ static int verify_ima(const char *file)
> }
> }
>
> - return ima_verify_signature(file, sig, len, NULL, 0);
> + return ima_verify_signature2(public_keys, file, sig, len, NULL, 0);
> }
>
> static int cmd_verify_ima(struct command *cmd)
> {
> char *file = g_argv[optind++];
> + void *public_keys = NULL;
> int err, fails = 0;
>
> - if (imaevm_params.x509) {
> - if (imaevm_params.keyfile) /* Support multiple public keys */
> - init_public_keys(imaevm_params.keyfile);
> - else /* assume read pubkey from x509 cert */
> - init_public_keys("/etc/keys/x509_evm.der");
> - }
> -
> if (!file) {
> log_err("Parameters missing\n");
> print_usage(cmd);
> return -1;
> }
>
> + if (imaevm_params.x509) {
> + if (imaevm_params.keyfile) /* Support multiple public keys */
> + init_public_keys2(imaevm_params.keyfile, &public_keys);
> + else /* assume read pubkey from x509 cert */
> + init_public_keys2("/etc/keys/x509_evm.der", &public_keys);
You should probably check the return code of this function.
> + }
> +
> do {
> - err = verify_ima(file);
> + err = verify_ima(public_keys, file);
> if (err)
> fails++;
> if (!err && imaevm_params.verbose >= LOG_INFO)
> log_info("%s: verification is OK\n", file);
> } while ((file = g_argv[optind++]));
> +
> + free_public_keys(public_keys);
> return fails > 0;
> }
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 06/12] Update cmd_verify_evm to define and use a local list of public keys
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (4 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 05/12] Update cmd_verify_ima() to define and use a local list of public keys Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-19 16:50 ` [ima-evm-utils PATCH 07/12] Update ima_measurements " Mimi Zohar
` (5 subsequent siblings)
11 siblings, 0 replies; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Replace calling init_public_keys() with the init_public_keys2() version.
Similarly replace verify_hash() with the verify_hash2() version.
Update the static function verify_evm() definition to include a
"public_keys" parameter.
Free the local public keys list.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/evmctl.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index bf1f8f07e9ca..f796edfce5f1 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -905,7 +905,7 @@ static int cmd_sign_evm(struct command *cmd)
return do_cmd(cmd, sign_evm_path);
}
-static int verify_evm(const char *file)
+static int verify_evm(void *public_keys, const char *file)
{
unsigned char hash[MAX_DIGEST_SIZE];
unsigned char sig[MAX_SIGNATURE_SIZE];
@@ -945,12 +945,14 @@ static int verify_evm(const char *file)
return mdlen;
assert(mdlen <= sizeof(hash));
- return verify_hash(file, hash, mdlen, sig, len);
+ return verify_hash2(public_keys, file, imaevm_params.hash_algo,
+ hash, mdlen, sig, len);
}
static int cmd_verify_evm(struct command *cmd)
{
char *file = g_argv[optind++];
+ void *public_keys = NULL;
int err;
if (!file) {
@@ -961,14 +963,17 @@ static int cmd_verify_evm(struct command *cmd)
if (imaevm_params.x509) {
if (imaevm_params.keyfile) /* Support multiple public keys */
- init_public_keys(imaevm_params.keyfile);
+ init_public_keys2(imaevm_params.keyfile, &public_keys);
else /* assume read pubkey from x509 cert */
- init_public_keys("/etc/keys/x509_evm.der");
+ init_public_keys2("/etc/keys/x509_evm.der",
+ &public_keys);
}
- err = verify_evm(file);
+ err = verify_evm(public_keys, file);
if (!err && imaevm_params.verbose >= LOG_INFO)
log_info("%s: verification is OK\n", file);
+
+ free_public_keys(public_keys);
return err;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [ima-evm-utils PATCH 07/12] Update ima_measurements to define and use a local list of public keys
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (5 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 06/12] Update cmd_verify_evm " Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:24 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 08/12] Define library ima_calc_hash2() function with a hash algorithm parameter Mimi Zohar
` (4 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Replace calling init_public_keys() with the init_public_keys2() version.
Similarly replace ima_verify_signature() with the ima_verify_signature2()
version.
Update the static ima_ng_show() function definition to include a
"public_keys" parameter.
Free the local public keys list.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/evmctl.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index f796edfce5f1..ad4565b3ee52 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1614,7 +1614,7 @@ static int lookup_template_name_entry(char *template_name)
return 0;
}
-void ima_ng_show(struct template_entry *entry)
+static void ima_ng_show(void *public_keys, struct template_entry *entry)
{
uint8_t *fieldp = entry->template;
uint32_t field_len;
@@ -1740,10 +1740,12 @@ void ima_ng_show(struct template_entry *entry)
* the measurement list or calculate the hash.
*/
if (verify_list_sig)
- err = ima_verify_signature(path, sig, sig_len,
- digest, digest_len);
+ err = ima_verify_signature2(public_keys, path,
+ sig, sig_len,
+ digest, digest_len);
else
- err = ima_verify_signature(path, sig, sig_len, NULL, 0);
+ err = ima_verify_signature2(public_keys, path,
+ sig, sig_len, NULL, 0);
if (!err && imaevm_params.verbose > LOG_INFO)
log_info("%s: verification is OK\n", path);
@@ -2223,6 +2225,7 @@ static int ima_measurement(const char *file)
int first_record = 1;
unsigned int pseudo_padded_banks_mask, pseudo_banks_mask;
unsigned long entry_num = 0;
+ void *public_keys = NULL;
int c;
struct template_entry entry = { .template = NULL };
@@ -2252,9 +2255,9 @@ static int ima_measurement(const char *file)
}
if (imaevm_params.keyfile) /* Support multiple public keys */
- init_public_keys(imaevm_params.keyfile);
+ init_public_keys2(imaevm_params.keyfile, &public_keys);
else /* assume read pubkey from x509 cert */
- init_public_keys("/etc/keys/x509_evm.der");
+ init_public_keys2("/etc/keys/x509_evm.der", &public_keys);
if (errno)
log_errno_reset(LOG_DEBUG,
"Failure in initializing public keys");
@@ -2405,7 +2408,7 @@ static int ima_measurement(const char *file)
if (is_ima_template)
ima_show(&entry);
else
- ima_ng_show(&entry);
+ ima_ng_show(public_keys, &entry);
if (!tpmbanks)
continue;
@@ -2464,6 +2467,7 @@ out_free:
free(pseudo_banks);
free(pseudo_padded_banks);
free(entry.template);
+ free_public_keys(public_keys);
return err;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 07/12] Update ima_measurements to define and use a local list of public keys
2023-11-19 16:50 ` [ima-evm-utils PATCH 07/12] Update ima_measurements " Mimi Zohar
@ 2023-11-22 13:24 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:24 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Replace calling init_public_keys() with the init_public_keys2() version.
> Similarly replace ima_verify_signature() with the ima_verify_signature2()
> version.
>
> Update the static ima_ng_show() function definition to include a
> "public_keys" parameter.
>
> Free the local public keys list.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/evmctl.c | 18 +++++++++++-------
> 1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/src/evmctl.c b/src/evmctl.c
> index f796edfce5f1..ad4565b3ee52 100644
> --- a/src/evmctl.c
> +++ b/src/evmctl.c
> @@ -1614,7 +1614,7 @@ static int lookup_template_name_entry(char *template_name)
> return 0;
> }
>
> -void ima_ng_show(struct template_entry *entry)
> +static void ima_ng_show(void *public_keys, struct template_entry *entry)
> {
> uint8_t *fieldp = entry->template;
> uint32_t field_len;
> @@ -1740,10 +1740,12 @@ void ima_ng_show(struct template_entry *entry)
> * the measurement list or calculate the hash.
> */
> if (verify_list_sig)
> - err = ima_verify_signature(path, sig, sig_len,
> - digest, digest_len);
> + err = ima_verify_signature2(public_keys, path,
> + sig, sig_len,
> + digest, digest_len);
> else
> - err = ima_verify_signature(path, sig, sig_len, NULL, 0);
> + err = ima_verify_signature2(public_keys, path,
> + sig, sig_len, NULL, 0);
>
> if (!err && imaevm_params.verbose > LOG_INFO)
> log_info("%s: verification is OK\n", path);
> @@ -2223,6 +2225,7 @@ static int ima_measurement(const char *file)
> int first_record = 1;
> unsigned int pseudo_padded_banks_mask, pseudo_banks_mask;
> unsigned long entry_num = 0;
> + void *public_keys = NULL;
> int c;
>
> struct template_entry entry = { .template = NULL };
> @@ -2252,9 +2255,9 @@ static int ima_measurement(const char *file)
> }
>
> if (imaevm_params.keyfile) /* Support multiple public keys */
> - init_public_keys(imaevm_params.keyfile);
> + init_public_keys2(imaevm_params.keyfile, &public_keys);
> else /* assume read pubkey from x509 cert */
> - init_public_keys("/etc/keys/x509_evm.der");
> + init_public_keys2("/etc/keys/x509_evm.der", &public_keys);
> if (errno)
Hm, a failing malloc() sets errno, so this would be ok. I would change
this to check for return value != 0 from init_public_keys2().
> log_errno_reset(LOG_DEBUG,
> "Failure in initializing public keys");
> @@ -2405,7 +2408,7 @@ static int ima_measurement(const char *file)
> if (is_ima_template)
> ima_show(&entry);
> else
> - ima_ng_show(&entry);
> + ima_ng_show(public_keys, &entry);
>
> if (!tpmbanks)
> continue;
> @@ -2464,6 +2467,7 @@ out_free:
> free(pseudo_banks);
> free(pseudo_padded_banks);
> free(entry.template);
> + free_public_keys(public_keys);
>
> return err;
> }
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 08/12] Define library ima_calc_hash2() function with a hash algorithm parameter
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (6 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 07/12] Update ima_measurements " Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:26 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures Mimi Zohar
` (3 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on the "imaevm_params.algo" global variable, which
is not concurrency-safe, define a new library ima_calc_hash2() function
with the hash algorithm as a parameter.
To avoid library incompatablity, make the existing ima_calc_hash()
function a wrapper for ima_calc_hash2().
Deprecate ima_calc_hash().
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/imaevm.h | 1 +
src/libimaevm.c | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/imaevm.h b/src/imaevm.h
index 1ed2c81d510d..81acd8df41cb 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -237,6 +237,7 @@ extern struct libimaevm_params imaevm_params;
void imaevm_do_hexdump(FILE *fp, const void *ptr, int len, bool cr);
void imaevm_hexdump(const void *ptr, int len);
int ima_calc_hash(const char *file, uint8_t *hash);
+int ima_calc_hash2(const char *file, const char *hash_algo, uint8_t *hash);
int imaevm_get_hash_algo(const char *algo);
RSA *read_pub_key(const char *keyfile, int x509);
EVP_PKEY *read_pub_pkey(const char *keyfile, int x509);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index e64d167a2a8a..4c9da7a2f06b 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -181,7 +181,7 @@ out:
return err;
}
-int ima_calc_hash(const char *file, uint8_t *hash)
+int ima_calc_hash2(const char *file, const char *hash_algo, uint8_t *hash)
{
const EVP_MD *md;
struct stat st;
@@ -202,10 +202,9 @@ int ima_calc_hash(const char *file, uint8_t *hash)
goto err;
}
- md = EVP_get_digestbyname(imaevm_params.hash_algo);
+ md = EVP_get_digestbyname(hash_algo);
if (!md) {
- log_err("EVP_get_digestbyname(%s) failed\n",
- imaevm_params.hash_algo);
+ log_err("EVP_get_digestbyname(%s) failed\n", hash_algo);
err = 1;
goto err;
}
@@ -246,6 +245,11 @@ err:
return err;
}
+int ima_calc_hash(const char *file, uint8_t *hash)
+{
+ return ima_calc_hash2(file, imaevm_params.hash_algo, hash);
+}
+
EVP_PKEY *read_pub_pkey(const char *keyfile, int x509)
{
FILE *fp;
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 08/12] Define library ima_calc_hash2() function with a hash algorithm parameter
2023-11-19 16:50 ` [ima-evm-utils PATCH 08/12] Define library ima_calc_hash2() function with a hash algorithm parameter Mimi Zohar
@ 2023-11-22 13:26 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:26 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on the "imaevm_params.algo" global variable, which
> is not concurrency-safe, define a new library ima_calc_hash2() function
> with the hash algorithm as a parameter.
>
> To avoid library incompatablity, make the existing ima_calc_hash()
-> incompatibility
> function a wrapper for ima_calc_hash2().
>
> Deprecate ima_calc_hash().
Same comment about possible __attribute__((deprecated)).
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/imaevm.h | 1 +
> src/libimaevm.c | 12 ++++++++----
> 2 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/src/imaevm.h b/src/imaevm.h
> index 1ed2c81d510d..81acd8df41cb 100644
> --- a/src/imaevm.h
> +++ b/src/imaevm.h
> @@ -237,6 +237,7 @@ extern struct libimaevm_params imaevm_params;
> void imaevm_do_hexdump(FILE *fp, const void *ptr, int len, bool cr);
> void imaevm_hexdump(const void *ptr, int len);
> int ima_calc_hash(const char *file, uint8_t *hash);
> +int ima_calc_hash2(const char *file, const char *hash_algo, uint8_t *hash);
> int imaevm_get_hash_algo(const char *algo);
> RSA *read_pub_key(const char *keyfile, int x509);
> EVP_PKEY *read_pub_pkey(const char *keyfile, int x509);
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index e64d167a2a8a..4c9da7a2f06b 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -181,7 +181,7 @@ out:
> return err;
> }
>
> -int ima_calc_hash(const char *file, uint8_t *hash)
> +int ima_calc_hash2(const char *file, const char *hash_algo, uint8_t *hash)
> {
> const EVP_MD *md;
> struct stat st;
> @@ -202,10 +202,9 @@ int ima_calc_hash(const char *file, uint8_t *hash)
> goto err;
> }
>
> - md = EVP_get_digestbyname(imaevm_params.hash_algo);
> + md = EVP_get_digestbyname(hash_algo);
> if (!md) {
> - log_err("EVP_get_digestbyname(%s) failed\n",
> - imaevm_params.hash_algo);
> + log_err("EVP_get_digestbyname(%s) failed\n", hash_algo);
> err = 1;
> goto err;
> }
> @@ -246,6 +245,11 @@ err:
> return err;
> }
>
> +int ima_calc_hash(const char *file, uint8_t *hash)
> +{
> + return ima_calc_hash2(file, imaevm_params.hash_algo, hash);
> +}
> +
> EVP_PKEY *read_pub_pkey(const char *keyfile, int x509)
> {
> FILE *fp;
Rest looks good to me.
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (7 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 08/12] Define library ima_calc_hash2() function with a hash algorithm parameter Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:37 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 10/12] Update EVM signature verification to use a local hash algorithm variable Mimi Zohar
` (2 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on the "imaevm_params.algo" global variable, which
is not concurrency-safe, define and use a local variable.
Update static verify_hash_v2(), verify_hash_v3(), and verify_hash_common()
function definitions to include a hash algorithm argument.
Similarly update ima_verify_signature2() and ima_calc_hash2() to define
and use a local hash algorithm variable.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/libimaevm.c | 40 ++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 4c9da7a2f06b..18b6a6f27237 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -488,6 +488,7 @@ void init_public_keys(const char *keyfiles)
* (Note: signature_v2_hdr struct does not contain the 'type'.)
*/
static int verify_hash_common(void *public_keys, const char *file,
+ const char *hash_algo,
const unsigned char *hash,
int size, unsigned char *sig, int siglen)
{
@@ -499,7 +500,7 @@ static int verify_hash_common(void *public_keys, const char *file,
const char *st;
if (imaevm_params.verbose > LOG_INFO) {
- log_info("hash(%s): ", imaevm_params.hash_algo);
+ log_info("hash(%s): ", hash_algo);
log_dump(hash, size);
}
@@ -530,7 +531,7 @@ static int verify_hash_common(void *public_keys, const char *file,
if (!EVP_PKEY_verify_init(ctx))
goto err;
st = "EVP_get_digestbyname";
- if (!(md = EVP_get_digestbyname(imaevm_params.hash_algo)))
+ if (!(md = EVP_get_digestbyname(hash_algo)))
goto err;
st = "EVP_PKEY_CTX_set_signature_md";
if (!EVP_PKEY_CTX_set_signature_md(ctx, md))
@@ -566,11 +567,12 @@ err:
* Return: 0 verification good, 1 verification bad, -1 error.
*/
static int verify_hash_v2(void *public_keys, const char *file,
+ const char *hash_algo,
const unsigned char *hash,
int size, unsigned char *sig, int siglen)
{
/* note: signature_v2_hdr does not contain 'type', use sig + 1 */
- return verify_hash_common(public_keys, file, hash, size,
+ return verify_hash_common(public_keys, file, hash_algo, hash, size,
sig + 1, siglen - 1);
}
@@ -581,19 +583,20 @@ static int verify_hash_v2(void *public_keys, const char *file,
* Return: 0 verification good, 1 verification bad, -1 error.
*/
static int verify_hash_v3(void *public_keys, const char *file,
+ const char *hash_algo,
const unsigned char *hash,
int size, unsigned char *sig, int siglen)
{
unsigned char sigv3_hash[MAX_DIGEST_SIZE];
int ret;
- ret = calc_hash_sigv3(sig[0], NULL, hash, sigv3_hash);
+ ret = calc_hash_sigv3(sig[0], hash_algo, hash, sigv3_hash);
if (ret < 0)
return ret;
/* note: signature_v2_hdr does not contain 'type', use sig + 1 */
- return verify_hash_common(public_keys, file, sigv3_hash, size,
- sig + 1, siglen - 1);
+ return verify_hash_common(public_keys, file, hash_algo, sigv3_hash,
+ size, sig + 1, siglen - 1);
}
#define HASH_MAX_DIGESTSIZE 64 /* kernel HASH_MAX_DIGESTSIZE is 64 bytes */
@@ -636,8 +639,10 @@ int calc_hash_sigv3(enum evm_ima_xattr_type type, const char *algo,
return -EINVAL;
}
- if (!algo)
- algo = imaevm_params.hash_algo;
+ if (!algo) {
+ log_err("Hash algorithm unspecified\n");
+ return -EINVAL;
+ }
if ((hash_algo = imaevm_get_hash_algo(algo)) < 0) {
log_err("Hash algorithm %s not supported\n", algo);
@@ -757,10 +762,10 @@ int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
return -1;
#endif
} else if (sig[1] == DIGSIG_VERSION_2) {
- return verify_hash_v2(public_keys, file, hash, size,
+ return verify_hash_v2(public_keys, file, hash_algo, hash, size,
sig, siglen);
} else if (sig[1] == DIGSIG_VERSION_3) {
- return verify_hash_v3(public_keys, file, hash, size,
+ return verify_hash_v3(public_keys, file, hash_algo, hash, size,
sig, siglen);
} else
return -1;
@@ -774,7 +779,8 @@ int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
int verify_hash(const char *file, const unsigned char *hash, int size,
unsigned char *sig, int siglen)
{
- return verify_hash2(g_public_keys, file, NULL, hash, size, sig, siglen);
+ return verify_hash2(g_public_keys, file, imaevm_params.hash_algo,
+ hash, size, sig, siglen);
}
int ima_verify_signature2(void *public_keys, const char *file,
@@ -783,6 +789,7 @@ int ima_verify_signature2(void *public_keys, const char *file,
{
unsigned char hash[MAX_DIGEST_SIZE];
int hashlen, sig_hash_algo;
+ const char *hash_algo;
if (sig[0] != EVM_IMA_XATTR_DIGSIG && sig[0] != IMA_VERITY_DIGSIG) {
log_err("%s: xattr ima has no signature\n", file);
@@ -800,22 +807,23 @@ int ima_verify_signature2(void *public_keys, const char *file,
return -1;
}
/* Use hash algorithm as retrieved from signature */
- imaevm_params.hash_algo = imaevm_hash_algo_by_id(sig_hash_algo);
+ hash_algo = imaevm_hash_algo_by_id(sig_hash_algo);
/*
* Validate the signature based on the digest included in the
* measurement list, not by calculating the local file digest.
*/
if (digest && digestlen > 0)
- return verify_hash2(public_keys, file, NULL, digest, digestlen,
- sig, siglen);
+ return verify_hash2(public_keys, file,
+ hash_algo, digest, digestlen,
+ sig, siglen);
- hashlen = ima_calc_hash(file, hash);
+ hashlen = ima_calc_hash2(file, hash_algo, hash);
if (hashlen <= 1)
return hashlen;
assert(hashlen <= sizeof(hash));
- return verify_hash2(public_keys, file, NULL, hash, hashlen,
+ return verify_hash2(public_keys, file, hash_algo, hash, hashlen,
sig, siglen);
}
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures
2023-11-19 16:50 ` [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures Mimi Zohar
@ 2023-11-22 13:37 ` Stefan Berger
2023-11-22 14:14 ` Mimi Zohar
0 siblings, 1 reply; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:37 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on the "imaevm_params.algo" global variable, which
> is not concurrency-safe, define and use a local variable.
>
> Update static verify_hash_v2(), verify_hash_v3(), and verify_hash_common()
> function definitions to include a hash algorithm argument.
>
> Similarly update ima_verify_signature2() and ima_calc_hash2() to define
> and use a local hash algorithm variable.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/libimaevm.c | 40 ++++++++++++++++++++++++----------------
> 1 file changed, 24 insertions(+), 16 deletions(-)
>
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index 4c9da7a2f06b..18b6a6f27237 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -488,6 +488,7 @@ void init_public_keys(const char *keyfiles)
> * (Note: signature_v2_hdr struct does not contain the 'type'.)
> */
> static int verify_hash_common(void *public_keys, const char *file,
> + const char *hash_algo,
> const unsigned char *hash,
> int size, unsigned char *sig, int siglen)
> {
> @@ -499,7 +500,7 @@ static int verify_hash_common(void *public_keys, const char *file,
> const char *st;
>
> if (imaevm_params.verbose > LOG_INFO) {
> - log_info("hash(%s): ", imaevm_params.hash_algo);
> + log_info("hash(%s): ", hash_algo);
> log_dump(hash, size);
> }
>
> @@ -530,7 +531,7 @@ static int verify_hash_common(void *public_keys, const char *file,
> if (!EVP_PKEY_verify_init(ctx))
> goto err;
> st = "EVP_get_digestbyname";
> - if (!(md = EVP_get_digestbyname(imaevm_params.hash_algo)))
> + if (!(md = EVP_get_digestbyname(hash_algo)))
> goto err;
> st = "EVP_PKEY_CTX_set_signature_md";
> if (!EVP_PKEY_CTX_set_signature_md(ctx, md))
> @@ -566,11 +567,12 @@ err:
> * Return: 0 verification good, 1 verification bad, -1 error.
> */
> static int verify_hash_v2(void *public_keys, const char *file,
> + const char *hash_algo,
> const unsigned char *hash,
> int size, unsigned char *sig, int siglen)
> {
> /* note: signature_v2_hdr does not contain 'type', use sig + 1 */
> - return verify_hash_common(public_keys, file, hash, size,
> + return verify_hash_common(public_keys, file, hash_algo, hash, size,
> sig + 1, siglen - 1);
> }
>
> @@ -581,19 +583,20 @@ static int verify_hash_v2(void *public_keys, const char *file,
> * Return: 0 verification good, 1 verification bad, -1 error.
> */
> static int verify_hash_v3(void *public_keys, const char *file,
> + const char *hash_algo,
> const unsigned char *hash,
> int size, unsigned char *sig, int siglen)
> {
> unsigned char sigv3_hash[MAX_DIGEST_SIZE];
> int ret;
>
> - ret = calc_hash_sigv3(sig[0], NULL, hash, sigv3_hash);
> + ret = calc_hash_sigv3(sig[0], hash_algo, hash, sigv3_hash);
> if (ret < 0)
> return ret;
>
> /* note: signature_v2_hdr does not contain 'type', use sig + 1 */
> - return verify_hash_common(public_keys, file, sigv3_hash, size,
> - sig + 1, siglen - 1);
> + return verify_hash_common(public_keys, file, hash_algo, sigv3_hash,
> + size, sig + 1, siglen - 1);
> }
>
> #define HASH_MAX_DIGESTSIZE 64 /* kernel HASH_MAX_DIGESTSIZE is 64 bytes */
> @@ -636,8 +639,10 @@ int calc_hash_sigv3(enum evm_ima_xattr_type type, const char *algo,
> return -EINVAL;
> }
>
> - if (!algo)
> - algo = imaevm_params.hash_algo;
> + if (!algo) {
> + log_err("Hash algorithm unspecified\n");
> + return -EINVAL;
> + }
>
> if ((hash_algo = imaevm_get_hash_algo(algo)) < 0) {
> log_err("Hash algorithm %s not supported\n", algo);
> @@ -757,10 +762,10 @@ int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
> return -1;
> #endif
> } else if (sig[1] == DIGSIG_VERSION_2) {
> - return verify_hash_v2(public_keys, file, hash, size,
> + return verify_hash_v2(public_keys, file, hash_algo, hash, size,
> sig, siglen);
> } else if (sig[1] == DIGSIG_VERSION_3) {
> - return verify_hash_v3(public_keys, file, hash, size,
> + return verify_hash_v3(public_keys, file, hash_algo, hash, size,
> sig, siglen);
> } else
> return -1;
> @@ -774,7 +779,8 @@ int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
> int verify_hash(const char *file, const unsigned char *hash, int size,
> unsigned char *sig, int siglen)
> {
> - return verify_hash2(g_public_keys, file, NULL, hash, size, sig, siglen);
> + return verify_hash2(g_public_keys, file, imaevm_params.hash_algo,
> + hash, size, sig, siglen);
Now you are passing valid parameters into verify_hash2(). Would it not
be possible to drop 4/12?
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures
2023-11-22 13:37 ` Stefan Berger
@ 2023-11-22 14:14 ` Mimi Zohar
2023-11-22 14:33 ` Stefan Berger
0 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-22 14:14 UTC (permalink / raw)
To: Stefan Berger, linux-integrity
On Wed, 2023-11-22 at 08:37 -0500, Stefan Berger wrote:
>
> On 11/19/23 11:50, Mimi Zohar wrote:
> > Instead of relying on the "imaevm_params.algo" global variable, which
> > is not concurrency-safe, define and use a local variable.
> >
> > Update static verify_hash_v2(), verify_hash_v3(), and verify_hash_common()
> > function definitions to include a hash algorithm argument.
> >
> > Similarly update ima_verify_signature2() and ima_calc_hash2() to define
> > and use a local hash algorithm variable.
> >
> > Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> > ---
> > src/libimaevm.c | 40 ++++++++++++++++++++++++----------------
> > 1 file changed, 24 insertions(+), 16 deletions(-)
> >
> > diff --git a/src/libimaevm.c b/src/libimaevm.c
> > index 4c9da7a2f06b..18b6a6f27237 100644
> > --- a/src/libimaevm.c
> > +++ b/src/libimaevm.c
> > @@ -488,6 +488,7 @@ void init_public_keys(const char *keyfiles)
> > * (Note: signature_v2_hdr struct does not contain the 'type'.)
> > */
> > static int verify_hash_common(void *public_keys, const char *file,
> > + const char *hash_algo,
> > const unsigned char *hash,
> > int size, unsigned char *sig, int siglen)
> > {
> > @@ -499,7 +500,7 @@ static int verify_hash_common(void *public_keys, const char *file,
> > const char *st;
> >
> > if (imaevm_params.verbose > LOG_INFO) {
> > - log_info("hash(%s): ", imaevm_params.hash_algo);
> > + log_info("hash(%s): ", hash_algo);
> > log_dump(hash, size);
> > }
> >
> > @@ -530,7 +531,7 @@ static int verify_hash_common(void *public_keys, const char *file,
> > if (!EVP_PKEY_verify_init(ctx))
> > goto err;
> > st = "EVP_get_digestbyname";
> > - if (!(md = EVP_get_digestbyname(imaevm_params.hash_algo)))
> > + if (!(md = EVP_get_digestbyname(hash_algo)))
> > goto err;
> > st = "EVP_PKEY_CTX_set_signature_md";
> > if (!EVP_PKEY_CTX_set_signature_md(ctx, md))
> > @@ -566,11 +567,12 @@ err:
> > * Return: 0 verification good, 1 verification bad, -1 error.
> > */
> > static int verify_hash_v2(void *public_keys, const char *file,
> > + const char *hash_algo,
> > const unsigned char *hash,
> > int size, unsigned char *sig, int siglen)
> > {
> > /* note: signature_v2_hdr does not contain 'type', use sig + 1 */
> > - return verify_hash_common(public_keys, file, hash, size,
> > + return verify_hash_common(public_keys, file, hash_algo, hash, size,
> > sig + 1, siglen - 1);
> > }
> >
> > @@ -581,19 +583,20 @@ static int verify_hash_v2(void *public_keys, const char *file,
> > * Return: 0 verification good, 1 verification bad, -1 error.
> > */
> > static int verify_hash_v3(void *public_keys, const char *file,
> > + const char *hash_algo,
> > const unsigned char *hash,
> > int size, unsigned char *sig, int siglen)
> > {
> > unsigned char sigv3_hash[MAX_DIGEST_SIZE];
> > int ret;
> >
> > - ret = calc_hash_sigv3(sig[0], NULL, hash, sigv3_hash);
> > + ret = calc_hash_sigv3(sig[0], hash_algo, hash, sigv3_hash);
> > if (ret < 0)
> > return ret;
> >
> > /* note: signature_v2_hdr does not contain 'type', use sig + 1 */
> > - return verify_hash_common(public_keys, file, sigv3_hash, size,
> > - sig + 1, siglen - 1);
> > + return verify_hash_common(public_keys, file, hash_algo, sigv3_hash,
> > + size, sig + 1, siglen - 1);
> > }
> >
> > #define HASH_MAX_DIGESTSIZE 64 /* kernel HASH_MAX_DIGESTSIZE is 64 bytes */
> > @@ -636,8 +639,10 @@ int calc_hash_sigv3(enum evm_ima_xattr_type type, const char *algo,
> > return -EINVAL;
> > }
> >
> > - if (!algo)
> > - algo = imaevm_params.hash_algo;
> > + if (!algo) {
> > + log_err("Hash algorithm unspecified\n");
> > + return -EINVAL;
> > + }
> >
> > if ((hash_algo = imaevm_get_hash_algo(algo)) < 0) {
> > log_err("Hash algorithm %s not supported\n", algo);
> > @@ -757,10 +762,10 @@ int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
> > return -1;
> > #endif
> > } else if (sig[1] == DIGSIG_VERSION_2) {
> > - return verify_hash_v2(public_keys, file, hash, size,
> > + return verify_hash_v2(public_keys, file, hash_algo, hash, size,
> > sig, siglen);
> > } else if (sig[1] == DIGSIG_VERSION_3) {
> > - return verify_hash_v3(public_keys, file, hash, size,
> > + return verify_hash_v3(public_keys, file, hash_algo, hash, size,
> > sig, siglen);
> > } else
> > return -1;
> > @@ -774,7 +779,8 @@ int verify_hash2(void *public_keys, const char *file, const char *hash_algo,
> > int verify_hash(const char *file, const unsigned char *hash, int size,
> > unsigned char *sig, int siglen)
> > {
> > - return verify_hash2(g_public_keys, file, NULL, hash, size, sig, siglen);
> > + return verify_hash2(g_public_keys, file, imaevm_params.hash_algo,
> > + hash, size, sig, siglen);
>
> Now you are passing valid parameters into verify_hash2(). Would it not
> be possible to drop 4/12?
Just as we can't modify the library verify_hash() definition, I don't
think we should be modifying the verify_hash2() defintion either.
04/12 defines and exports the final verify_hash2() definition.
--
thanks,
Mimi
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures
2023-11-22 14:14 ` Mimi Zohar
@ 2023-11-22 14:33 ` Stefan Berger
2023-11-29 16:08 ` Mimi Zohar
0 siblings, 1 reply; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 14:33 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/22/23 09:14, Mimi Zohar wrote:
> On Wed, 2023-11-22 at 08:37 -0500, Stefan Berger wrote:
>>
>> Now you are passing valid parameters into verify_hash2(). Would it not
>> be possible to drop 4/12?
>
> Just as we can't modify the library verify_hash() definition, I don't
> think we should be modifying the verify_hash2() defintion either.
> 04/12 defines and exports the final verify_hash2() definition.
>
The question is whether verify_hash2() can be only introduced here in
versus made available in 4/12 with a parameter that it doesn't use at
all at that point.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures
2023-11-22 14:33 ` Stefan Berger
@ 2023-11-29 16:08 ` Mimi Zohar
0 siblings, 0 replies; 28+ messages in thread
From: Mimi Zohar @ 2023-11-29 16:08 UTC (permalink / raw)
To: Stefan Berger, linux-integrity
On Wed, 2023-11-22 at 09:33 -0500, Stefan Berger wrote:
>
> On 11/22/23 09:14, Mimi Zohar wrote:
> > On Wed, 2023-11-22 at 08:37 -0500, Stefan Berger wrote:
> >>
>
> >> Now you are passing valid parameters into verify_hash2(). Would it not
> >> be possible to drop 4/12?
> >
> > Just as we can't modify the library verify_hash() definition, I don't
> > think we should be modifying the verify_hash2() defintion either.
> > 04/12 defines and exports the final verify_hash2() definition.
> >
>
> The question is whether verify_hash2() can be only introduced here in
> versus made available in 4/12 with a parameter that it doesn't use at
> all at that point.
Correct, however 6/12 "Update cmd_verify_evm to define and use a local
list of public keys" calls verify_hash2().
--
thanks,
Mimi
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 10/12] Update EVM signature verification to use a local hash algorithm variable
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (8 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 09/12] Use a local hash algorithm variable when verifying file signatures Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 13:55 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 11/12] Use a file specific hash algorithm variable for signing files Mimi Zohar
2023-11-19 16:50 ` [ima-evm-utils PATCH 12/12] Define and use a file specific "keypass" variable Mimi Zohar
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on the "imaevm_params.algo" global variable, which
is not concurrency-safe, define and use a local file hash algorithm
variable.
Update calc_evm_hash(), verify_hash2().
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/evmctl.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index ad4565b3ee52..7ae897d8b8b3 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -340,7 +340,8 @@ err:
* Returns 0 for EVP_ function failures. Return -1 for other failures.
* Return hash algorithm size on success.
*/
-static int calc_evm_hash(const char *file, unsigned char *hash)
+static int calc_evm_hash(const char *file, const char *hash_algo,
+ unsigned char *hash)
{
const EVP_MD *md;
struct stat st;
@@ -408,10 +409,9 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
}
#endif
- md = EVP_get_digestbyname(imaevm_params.hash_algo);
+ md = EVP_get_digestbyname(hash_algo);
if (!md) {
- log_err("EVP_get_digestbyname(%s) failed\n",
- imaevm_params.hash_algo);
+ log_err("EVP_get_digestbyname(%s) failed\n", hash_algo);
err = 0;
goto out;
}
@@ -570,7 +570,7 @@ static int sign_evm(const char *file, const char *key)
unsigned char sig[MAX_SIGNATURE_SIZE];
int len, err;
- len = calc_evm_hash(file, hash);
+ len = calc_evm_hash(file, imaevm_params.hash_algo, hash);
if (len <= 1)
return len;
assert(len <= sizeof(hash));
@@ -909,6 +909,7 @@ static int verify_evm(void *public_keys, const char *file)
{
unsigned char hash[MAX_DIGEST_SIZE];
unsigned char sig[MAX_SIGNATURE_SIZE];
+ const char *hash_algo = NULL;
int sig_hash_algo;
int mdlen;
int len;
@@ -938,15 +939,15 @@ static int verify_evm(void *public_keys, const char *file)
log_err("unknown hash algo: %s\n", file);
return -1;
}
- imaevm_params.hash_algo = imaevm_hash_algo_by_id(sig_hash_algo);
+ hash_algo = imaevm_hash_algo_by_id(sig_hash_algo);
- mdlen = calc_evm_hash(file, hash);
+ mdlen = calc_evm_hash(file, hash_algo, hash);
if (mdlen <= 1)
return mdlen;
assert(mdlen <= sizeof(hash));
- return verify_hash2(public_keys, file, imaevm_params.hash_algo,
- hash, mdlen, sig, len);
+ return verify_hash2(public_keys, file, hash_algo, hash,
+ mdlen, sig, len);
}
static int cmd_verify_evm(struct command *cmd)
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 10/12] Update EVM signature verification to use a local hash algorithm variable
2023-11-19 16:50 ` [ima-evm-utils PATCH 10/12] Update EVM signature verification to use a local hash algorithm variable Mimi Zohar
@ 2023-11-22 13:55 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 13:55 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on the "imaevm_params.algo" global variable, which
> is not concurrency-safe, define and use a local file hash algorithm
> variable.
>
> Update calc_evm_hash(), verify_hash2().
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/evmctl.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/src/evmctl.c b/src/evmctl.c
> index ad4565b3ee52..7ae897d8b8b3 100644
> --- a/src/evmctl.c
> +++ b/src/evmctl.c
> @@ -340,7 +340,8 @@ err:
> * Returns 0 for EVP_ function failures. Return -1 for other failures.
> * Return hash algorithm size on success.
> */
> -static int calc_evm_hash(const char *file, unsigned char *hash)
> +static int calc_evm_hash(const char *file, const char *hash_algo,
> + unsigned char *hash)
> {
> const EVP_MD *md;
> struct stat st;
> @@ -408,10 +409,9 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
> }
> #endif
>
> - md = EVP_get_digestbyname(imaevm_params.hash_algo);
> + md = EVP_get_digestbyname(hash_algo);
> if (!md) {
> - log_err("EVP_get_digestbyname(%s) failed\n",
> - imaevm_params.hash_algo);
> + log_err("EVP_get_digestbyname(%s) failed\n", hash_algo);
> err = 0;
> goto out;
> }
> @@ -570,7 +570,7 @@ static int sign_evm(const char *file, const char *key)
> unsigned char sig[MAX_SIGNATURE_SIZE];
> int len, err;
>
> - len = calc_evm_hash(file, hash);
> + len = calc_evm_hash(file, imaevm_params.hash_algo, hash);
> if (len <= 1)
> return len;
> assert(len <= sizeof(hash));
> @@ -909,6 +909,7 @@ static int verify_evm(void *public_keys, const char *file)
> {
> unsigned char hash[MAX_DIGEST_SIZE];
> unsigned char sig[MAX_SIGNATURE_SIZE];
> + const char *hash_algo = NULL;
> int sig_hash_algo;
> int mdlen;
> int len;
> @@ -938,15 +939,15 @@ static int verify_evm(void *public_keys, const char *file)
> log_err("unknown hash algo: %s\n", file);
> return -1;
> }
> - imaevm_params.hash_algo = imaevm_hash_algo_by_id(sig_hash_algo);
> + hash_algo = imaevm_hash_algo_by_id(sig_hash_algo);
>
> - mdlen = calc_evm_hash(file, hash);
> + mdlen = calc_evm_hash(file, hash_algo, hash);
> if (mdlen <= 1)
> return mdlen;
> assert(mdlen <= sizeof(hash));
>
> - return verify_hash2(public_keys, file, imaevm_params.hash_algo,
> - hash, mdlen, sig, len);
> + return verify_hash2(public_keys, file, hash_algo, hash,
> + mdlen, sig, len);
> }
>
> static int cmd_verify_evm(struct command *cmd)
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 11/12] Use a file specific hash algorithm variable for signing files
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (9 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 10/12] Update EVM signature verification to use a local hash algorithm variable Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 14:09 ` Stefan Berger
2023-11-19 16:50 ` [ima-evm-utils PATCH 12/12] Define and use a file specific "keypass" variable Mimi Zohar
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on the library "imaevm_params.algo" global variable,
which is not concurrency-safe, define and use an evmctl file specific
hash algorithm variable.
Propogate using the file specific hash algorithm variable in sign_evm(),
sign_ima(), hash_ima(), and sign_hash() function.
Replace using the library function ima_calc_hash() with ima_calc_hash2().
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/evmctl.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 7ae897d8b8b3..b802eeb1bf15 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -140,6 +140,7 @@ static bool evm_immutable;
static bool evm_portable;
static bool veritysig;
static bool hwtpm;
+static char *hash_algo;
#define HMAC_FLAG_NO_UUID 0x0001
#define HMAC_FLAG_CAPS_SET 0x0002
@@ -570,12 +571,12 @@ static int sign_evm(const char *file, const char *key)
unsigned char sig[MAX_SIGNATURE_SIZE];
int len, err;
- len = calc_evm_hash(file, imaevm_params.hash_algo, hash);
+ len = calc_evm_hash(file, hash_algo, hash);
if (len <= 1)
return len;
assert(len <= sizeof(hash));
- len = sign_hash(imaevm_params.hash_algo, hash, len, key, NULL, sig + 1);
+ len = sign_hash(hash_algo, hash, len, key, NULL, sig + 1);
if (len <= 1)
return len;
assert(len < sizeof(sig));
@@ -609,10 +610,10 @@ static int hash_ima(const char *file)
{
unsigned char hash[MAX_DIGEST_SIZE + 2]; /* +2 byte xattr header */
int len, err, offset;
- int algo = imaevm_get_hash_algo(imaevm_params.hash_algo);
+ int algo = imaevm_get_hash_algo(hash_algo);
if (algo < 0) {
- log_err("Unknown hash algo: %s\n", imaevm_params.hash_algo);
+ log_err("Unknown hash algo: %s\n", hash_algo);
return -1;
}
if (algo > PKEY_HASH_SHA1) {
@@ -624,7 +625,7 @@ static int hash_ima(const char *file)
offset = 1;
}
- len = ima_calc_hash(file, hash + offset);
+ len = ima_calc_hash2(file, hash_algo, hash + offset);
if (len <= 1)
return len;
assert(len + offset <= sizeof(hash));
@@ -632,7 +633,7 @@ static int hash_ima(const char *file)
len += offset;
if (imaevm_params.verbose >= LOG_INFO)
- log_info("hash(%s): ", imaevm_params.hash_algo);
+ log_info("hash(%s): ", hash_algo);
if (sigdump || imaevm_params.verbose >= LOG_INFO)
imaevm_hexdump(hash, len);
@@ -656,12 +657,12 @@ static int sign_ima(const char *file, const char *key)
unsigned char sig[MAX_SIGNATURE_SIZE];
int len, err;
- len = ima_calc_hash(file, hash);
+ len = ima_calc_hash2(file, hash_algo, hash);
if (len <= 1)
return len;
assert(len <= sizeof(hash));
- len = sign_hash(imaevm_params.hash_algo, hash, len, key, NULL, sig + 1);
+ len = sign_hash(hash_algo, hash, len, key, NULL, sig + 1);
if (len <= 1)
return len;
assert(len < sizeof(sig));
@@ -854,7 +855,7 @@ static int cmd_sign_hash(struct command *cmd)
assert(hashlen / 2 <= sizeof(hash));
hex2bin(hash, line, hashlen / 2);
- siglen = sign_hash(imaevm_params.hash_algo, hash,
+ siglen = sign_hash(hash_algo, hash,
hashlen / 2, key, NULL, sig + 1);
sig[0] = EVM_IMA_XATTR_DIGSIG;
}
@@ -3077,7 +3078,7 @@ int main(int argc, char *argv[])
sigdump = 1;
break;
case 'a':
- imaevm_params.hash_algo = optarg;
+ hash_algo = optarg;
break;
case 'p':
if (optarg)
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 11/12] Use a file specific hash algorithm variable for signing files
2023-11-19 16:50 ` [ima-evm-utils PATCH 11/12] Use a file specific hash algorithm variable for signing files Mimi Zohar
@ 2023-11-22 14:09 ` Stefan Berger
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 14:09 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on the library "imaevm_params.algo" global variable,
> which is not concurrency-safe, define and use an evmctl file specific
> hash algorithm variable.
>
> Propogate using the file specific hash algorithm variable in sign_evm(),
-> Propagate
> sign_ima(), hash_ima(), and sign_hash() function.
>
> Replace using the library function ima_calc_hash() with ima_calc_hash2().
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/evmctl.c | 21 +++++++++++----------
> 1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/src/evmctl.c b/src/evmctl.c
> index 7ae897d8b8b3..b802eeb1bf15 100644
> --- a/src/evmctl.c
> +++ b/src/evmctl.c
> @@ -140,6 +140,7 @@ static bool evm_immutable;
> static bool evm_portable;
> static bool veritysig;
> static bool hwtpm;
> +static char *hash_algo;
g_hash_algo to avoid shadowing this variable in some cases where there
is a function parameter of the same name?
>
> #define HMAC_FLAG_NO_UUID 0x0001
> #define HMAC_FLAG_CAPS_SET 0x0002
> @@ -570,12 +571,12 @@ static int sign_evm(const char *file, const char *key)
Add hash_algo to the parameters here and call it sign_evm(file, key,
g_hash_algo)? It makes sense to pass the hash_algo into this function
that needs to know this for the signature and pushed the usage of global
variables further out.
> unsigned char sig[MAX_SIGNATURE_SIZE];
> int len, err;
>
> - len = calc_evm_hash(file, imaevm_params.hash_algo, hash);
> + len = calc_evm_hash(file, hash_algo, hash);
> if (len <= 1)
> return len;
> assert(len <= sizeof(hash));
>
> - len = sign_hash(imaevm_params.hash_algo, hash, len, key, NULL, sig + 1);
> + len = sign_hash(hash_algo, hash, len, key, NULL, sig + 1);
> if (len <= 1)
> return len;
> assert(len < sizeof(sig));
> @@ -609,10 +610,10 @@ static int hash_ima(const char *file)
> {
> unsigned char hash[MAX_DIGEST_SIZE + 2]; /* +2 byte xattr header */
> int len, err, offset;
> - int algo = imaevm_get_hash_algo(imaevm_params.hash_algo);
> + int algo = imaevm_get_hash_algo(hash_algo);
>
> if (algo < 0) {
> - log_err("Unknown hash algo: %s\n", imaevm_params.hash_algo);
> + log_err("Unknown hash algo: %s\n", hash_algo);
> return -1;
> }
> if (algo > PKEY_HASH_SHA1) {
> @@ -624,7 +625,7 @@ static int hash_ima(const char *file)
> offset = 1;
> }
>
> - len = ima_calc_hash(file, hash + offset);
> + len = ima_calc_hash2(file, hash_algo, hash + offset);
> if (len <= 1)
> return len;
> assert(len + offset <= sizeof(hash));
> @@ -632,7 +633,7 @@ static int hash_ima(const char *file)
> len += offset;
>
> if (imaevm_params.verbose >= LOG_INFO)
> - log_info("hash(%s): ", imaevm_params.hash_algo);
> + log_info("hash(%s): ", hash_algo);
>
> if (sigdump || imaevm_params.verbose >= LOG_INFO)
> imaevm_hexdump(hash, len);
> @@ -656,12 +657,12 @@ static int sign_ima(const char *file, const char *key)
> unsigned char sig[MAX_SIGNATURE_SIZE];
> int len, err;
>
> - len = ima_calc_hash(file, hash);
> + len = ima_calc_hash2(file, hash_algo, hash);
> if (len <= 1)
> return len;
> assert(len <= sizeof(hash));
>
> - len = sign_hash(imaevm_params.hash_algo, hash, len, key, NULL, sig + 1);
> + len = sign_hash(hash_algo, hash, len, key, NULL, sig + 1);
> if (len <= 1)
> return len;
> assert(len < sizeof(sig));
> @@ -854,7 +855,7 @@ static int cmd_sign_hash(struct command *cmd)
> assert(hashlen / 2 <= sizeof(hash));
> hex2bin(hash, line, hashlen / 2);
>
> - siglen = sign_hash(imaevm_params.hash_algo, hash,
> + siglen = sign_hash(hash_algo, hash,
> hashlen / 2, key, NULL, sig + 1);
> sig[0] = EVM_IMA_XATTR_DIGSIG;
> }
> @@ -3077,7 +3078,7 @@ int main(int argc, char *argv[])
> sigdump = 1;
> break;
> case 'a':
> - imaevm_params.hash_algo = optarg;
> + hash_algo = optarg;
> break;
> case 'p':
> if (optarg)
^ permalink raw reply [flat|nested] 28+ messages in thread
* [ima-evm-utils PATCH 12/12] Define and use a file specific "keypass" variable
2023-11-19 16:50 [ima-evm-utils PATCH 00/12] Address non concurrency-safe libimaevm global variables Mimi Zohar
` (10 preceding siblings ...)
2023-11-19 16:50 ` [ima-evm-utils PATCH 11/12] Use a file specific hash algorithm variable for signing files Mimi Zohar
@ 2023-11-19 16:50 ` Mimi Zohar
2023-11-22 14:22 ` Stefan Berger
11 siblings, 1 reply; 28+ messages in thread
From: Mimi Zohar @ 2023-11-19 16:50 UTC (permalink / raw)
To: linux-integrity; +Cc: Mimi Zohar
Instead of relying on the "imaevm_params.keypass" global variable, which
is not concurrency-safe, add keypass as a parameter to the static library
functions definitions. Update function callers.
To avoid library incompatablity, don't remove imaevm_params.keypass
variable.
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
src/evmctl.c | 9 +++++----
src/libimaevm.c | 17 ++++++++---------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index b802eeb1bf15..6d6160159a1f 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -141,6 +141,7 @@ static bool evm_portable;
static bool veritysig;
static bool hwtpm;
static char *hash_algo;
+static char *keypass;
#define HMAC_FLAG_NO_UUID 0x0001
#define HMAC_FLAG_CAPS_SET 0x0002
@@ -3082,9 +3083,9 @@ int main(int argc, char *argv[])
break;
case 'p':
if (optarg)
- imaevm_params.keypass = optarg;
+ keypass = optarg;
else
- imaevm_params.keypass = get_password();
+ keypass = get_password();
break;
case 'f':
sigfile = 1;
@@ -3226,8 +3227,8 @@ int main(int argc, char *argv[])
}
}
- if (!imaevm_params.keypass)
- imaevm_params.keypass = getenv("EVMCTL_KEY_PASSWORD");
+ if (!keypass)
+ keypass = getenv("EVMCTL_KEY_PASSWORD");
if (imaevm_params.keyfile != NULL &&
imaevm_params.eng == NULL &&
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 18b6a6f27237..10ec847da08a 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -1124,7 +1124,8 @@ static int get_hash_algo_v1(const char *algo)
}
static int sign_hash_v1(const char *hashalgo, const unsigned char *hash,
- int size, const char *keyfile, unsigned char *sig)
+ int size, const char *keyfile, const char *keypass,
+ unsigned char *sig)
{
int len = -1, hashalgo_idx;
SHA_CTX ctx;
@@ -1158,7 +1159,7 @@ static int sign_hash_v1(const char *hashalgo, const unsigned char *hash,
log_info("hash(%s): ", hashalgo);
log_dump(hash, size);
- key = read_priv_key(keyfile, imaevm_params.keypass);
+ key = read_priv_key(keyfile, keypass);
if (!key)
return -1;
@@ -1211,7 +1212,8 @@ out:
* Return: -1 signing error, >0 length of signature
*/
static int sign_hash_v2(const char *algo, const unsigned char *hash,
- int size, const char *keyfile, unsigned char *sig)
+ int size, const char *keyfile, const char *keypass,
+ unsigned char *sig)
{
struct signature_v2_hdr *hdr;
int len = -1;
@@ -1246,7 +1248,7 @@ static int sign_hash_v2(const char *algo, const unsigned char *hash,
log_info("hash(%s): ", algo);
log_dump(hash, size);
- pkey = read_priv_pkey(keyfile, imaevm_params.keypass);
+ pkey = read_priv_pkey(keyfile, keypass);
if (!pkey)
return -1;
@@ -1316,14 +1318,11 @@ err:
int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig)
{
- if (keypass)
- imaevm_params.keypass = keypass;
-
if (imaevm_params.x509)
- return sign_hash_v2(hashalgo, hash, size, keyfile, sig);
+ return sign_hash_v2(hashalgo, hash, size, keyfile, keypass, sig);
#if CONFIG_SIGV1
else
- return sign_hash_v1(hashalgo, hash, size, keyfile, sig);
+ return sign_hash_v1(hashalgo, hash, size, keyfile, keypass, sig);
#endif
log_info("Signature version 1 deprecated.");
return -1;
--
2.39.3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 12/12] Define and use a file specific "keypass" variable
2023-11-19 16:50 ` [ima-evm-utils PATCH 12/12] Define and use a file specific "keypass" variable Mimi Zohar
@ 2023-11-22 14:22 ` Stefan Berger
2023-11-29 16:07 ` Mimi Zohar
0 siblings, 1 reply; 28+ messages in thread
From: Stefan Berger @ 2023-11-22 14:22 UTC (permalink / raw)
To: Mimi Zohar, linux-integrity
On 11/19/23 11:50, Mimi Zohar wrote:
> Instead of relying on the "imaevm_params.keypass" global variable, which
> is not concurrency-safe, add keypass as a parameter to the static library
> functions definitions. Update function callers.
>
> To avoid library incompatablity, don't remove imaevm_params.keypass
> variable.
>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> src/evmctl.c | 9 +++++----
> src/libimaevm.c | 17 ++++++++---------
> 2 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/src/evmctl.c b/src/evmctl.c
> index b802eeb1bf15..6d6160159a1f 100644
> --- a/src/evmctl.c
> +++ b/src/evmctl.c
> @@ -141,6 +141,7 @@ static bool evm_portable;
> static bool veritysig;
> static bool hwtpm;
> static char *hash_algo;
> +static char *keypass;
>
> #define HMAC_FLAG_NO_UUID 0x0001
> #define HMAC_FLAG_CAPS_SET 0x0002
> @@ -3082,9 +3083,9 @@ int main(int argc, char *argv[])
> break;
> case 'p':
> if (optarg)
> - imaevm_params.keypass = optarg;
> + keypass = optarg;
> else
> - imaevm_params.keypass = get_password();
> + keypass = get_password();
> break;
> case 'f':
> sigfile = 1;
> @@ -3226,8 +3227,8 @@ int main(int argc, char *argv[])
> }
> }
>
> - if (!imaevm_params.keypass)
> - imaevm_params.keypass = getenv("EVMCTL_KEY_PASSWORD");
> + if (!keypass)
> + keypass = getenv("EVMCTL_KEY_PASSWORD");
>
> if (imaevm_params.keyfile != NULL &&
> imaevm_params.eng == NULL &&
The problem at this point in evmctl is that keypass is never passed to
anywhere. You have to pass it to sign_hash().
> diff --git a/src/libimaevm.c b/src/libimaevm.c
> index 18b6a6f27237..10ec847da08a 100644
> --- a/src/libimaevm.c
> +++ b/src/libimaevm.c
> @@ -1124,7 +1124,8 @@ static int get_hash_algo_v1(const char *algo)
> }
>
> static int sign_hash_v1(const char *hashalgo, const unsigned char *hash,
> - int size, const char *keyfile, unsigned char *sig)
> + int size, const char *keyfile, const char *keypass,
> + unsigned char *sig)
> {
> int len = -1, hashalgo_idx;
> SHA_CTX ctx;
> @@ -1158,7 +1159,7 @@ static int sign_hash_v1(const char *hashalgo, const unsigned char *hash,
> log_info("hash(%s): ", hashalgo);
> log_dump(hash, size);
>
> - key = read_priv_key(keyfile, imaevm_params.keypass);
> + key = read_priv_key(keyfile, keypass);
> if (!key)
> return -1;
>
> @@ -1211,7 +1212,8 @@ out:
> * Return: -1 signing error, >0 length of signature
> */
> static int sign_hash_v2(const char *algo, const unsigned char *hash,
> - int size, const char *keyfile, unsigned char *sig)
> + int size, const char *keyfile, const char *keypass,
> + unsigned char *sig)
> {
> struct signature_v2_hdr *hdr;
> int len = -1;
> @@ -1246,7 +1248,7 @@ static int sign_hash_v2(const char *algo, const unsigned char *hash,
> log_info("hash(%s): ", algo);
> log_dump(hash, size);
>
> - pkey = read_priv_pkey(keyfile, imaevm_params.keypass);
> + pkey = read_priv_pkey(keyfile, keypass);
> if (!pkey)
> return -1;
>
> @@ -1316,14 +1318,11 @@ err:
>
> int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig)
> {
> - if (keypass)
> - imaevm_params.keypass = keypass;
> -
I hope all library callers, other than evmctl, passed the keypass in
already, otherwise they could have set the password via
imaevm_params.keypass global and passed in NULL and for them this will
be a behavioral change. Anyway, you have no other choice to get rid of
imaevm_params as much as possible, so I guess it's ok.
It looks like at this point imaevm_params.keypass doesn't have a single
user anymore so you could rename it to 'unused1' or so in the stucture
since it will have zero effect for anyone to set it.
> if (imaevm_params.x509)
> - return sign_hash_v2(hashalgo, hash, size, keyfile, sig);
> + return sign_hash_v2(hashalgo, hash, size, keyfile, keypass, sig);
> #if CONFIG_SIGV1
> else
> - return sign_hash_v1(hashalgo, hash, size, keyfile, sig);
> + return sign_hash_v1(hashalgo, hash, size, keyfile, keypass, sig);
> #endif
> log_info("Signature version 1 deprecated.");
> return -1;
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [ima-evm-utils PATCH 12/12] Define and use a file specific "keypass" variable
2023-11-22 14:22 ` Stefan Berger
@ 2023-11-29 16:07 ` Mimi Zohar
0 siblings, 0 replies; 28+ messages in thread
From: Mimi Zohar @ 2023-11-29 16:07 UTC (permalink / raw)
To: Stefan Berger, linux-integrity
On Wed, 2023-11-22 at 09:22 -0500, Stefan Berger wrote:
>
> On 11/19/23 11:50, Mimi Zohar wrote:
> > Instead of relying on the "imaevm_params.keypass" global variable, which
> > is not concurrency-safe, add keypass as a parameter to the static library
> > functions definitions. Update function callers.
> >
> > To avoid library incompatablity, don't remove imaevm_params.keypass
> > variable.
> >
> > Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> > ---
> > src/evmctl.c | 9 +++++----
> > src/libimaevm.c | 17 ++++++++---------
> > 2 files changed, 13 insertions(+), 13 deletions(-)
> >
> > diff --git a/src/evmctl.c b/src/evmctl.c
> > index b802eeb1bf15..6d6160159a1f 100644
> > --- a/src/evmctl.c
> > +++ b/src/evmctl.c
> > @@ -141,6 +141,7 @@ static bool evm_portable;
> > static bool veritysig;
> > static bool hwtpm;
> > static char *hash_algo;
> > +static char *keypass;
> >
> > #define HMAC_FLAG_NO_UUID 0x0001
> > #define HMAC_FLAG_CAPS_SET 0x0002
> > @@ -3082,9 +3083,9 @@ int main(int argc, char *argv[])
> > break;
> > case 'p':
> > if (optarg)
> > - imaevm_params.keypass = optarg;
> > + keypass = optarg;
> > else
> > - imaevm_params.keypass = get_password();
> > + keypass = get_password();
> > break;
> > case 'f':
> > sigfile = 1;
> > @@ -3226,8 +3227,8 @@ int main(int argc, char *argv[])
> > }
> > }
> >
> > - if (!imaevm_params.keypass)
> > - imaevm_params.keypass = getenv("EVMCTL_KEY_PASSWORD");
> > + if (!keypass)
> > + keypass = getenv("EVMCTL_KEY_PASSWORD");
> >
> > if (imaevm_params.keyfile != NULL &&
> > imaevm_params.eng == NULL &&
>
>
> The problem at this point in evmctl is that keypass is never passed to
> anywhere. You have to pass it to sign_hash().
Thanks for catching this. Part of the patch was missing was obviously
missing.
>
> > diff --git a/src/libimaevm.c b/src/libimaevm.c
> > index 18b6a6f27237..10ec847da08a 100644
> > --- a/src/libimaevm.c
> > +++ b/src/libimaevm.c
> > @@ -1124,7 +1124,8 @@ static int get_hash_algo_v1(const char *algo)
> > }
> >
> > static int sign_hash_v1(const char *hashalgo, const unsigned char *hash,
> > - int size, const char *keyfile, unsigned char *sig)
> > + int size, const char *keyfile, const char *keypass,
> > + unsigned char *sig)
> > {
> > int len = -1, hashalgo_idx;
> > SHA_CTX ctx;
> > @@ -1158,7 +1159,7 @@ static int sign_hash_v1(const char *hashalgo, const unsigned char *hash,
> > log_info("hash(%s): ", hashalgo);
> > log_dump(hash, size);
> >
> > - key = read_priv_key(keyfile, imaevm_params.keypass);
> > + key = read_priv_key(keyfile, keypass);
> > if (!key)
> > return -1;
> >
> > @@ -1211,7 +1212,8 @@ out:
> > * Return: -1 signing error, >0 length of signature
> > */
> > static int sign_hash_v2(const char *algo, const unsigned char *hash,
> > - int size, const char *keyfile, unsigned char *sig)
> > + int size, const char *keyfile, const char *keypass,
> > + unsigned char *sig)
> > {
> > struct signature_v2_hdr *hdr;
> > int len = -1;
> > @@ -1246,7 +1248,7 @@ static int sign_hash_v2(const char *algo, const unsigned char *hash,
> > log_info("hash(%s): ", algo);
> > log_dump(hash, size);
> >
> > - pkey = read_priv_pkey(keyfile, imaevm_params.keypass);
> > + pkey = read_priv_pkey(keyfile, keypass);
> > if (!pkey)
> > return -1;
> >
> > @@ -1316,14 +1318,11 @@ err:
> >
> > int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig)
> > {
> > - if (keypass)
> > - imaevm_params.keypass = keypass;
> > -
>
> I hope all library callers, other than evmctl, passed the keypass in
> already, otherwise they could have set the password via
> imaevm_params.keypass global and passed in NULL and for them this will
> be a behavioral change. Anyway, you have no other choice to get rid of
> imaevm_params as much as possible, so I guess it's ok.
For now we could invert the test and do exactly the opposite, like
this:
+ if (!keypass) /* Avoid breaking existing libimaevm usage */
+ keypass = imaevm_params.keypass;
+
thanks,
Mimi
>
> It looks like at this point imaevm_params.keypass doesn't have a single
> user anymore so you could rename it to 'unused1' or so in the stucture
> since it will have zero effect for anyone to set it.
>
> > if (imaevm_params.x509)
> > - return sign_hash_v2(hashalgo, hash, size, keyfile, sig);
> > + return sign_hash_v2(hashalgo, hash, size, keyfile, keypass, sig);
> > #if CONFIG_SIGV1
> > else
> > - return sign_hash_v1(hashalgo, hash, size, keyfile, sig);
> > + return sign_hash_v1(hashalgo, hash, size, keyfile, keypass, sig);
> > #endif
> > log_info("Signature version 1 deprecated.");
> > return -1;
^ permalink raw reply [flat|nested] 28+ messages in thread