* [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API
@ 2019-06-20 7:12 Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 01/11] ima-evm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE Vitaly Chikunov
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Convert sign v2 from RSA API (with manual formatting PKCS1) to more generic
EVP_PKEY API, allowing to generate more types of OpenSSL supported signatures.
This is done to enable EC-RDSA signatures, which are already supported in the
Kernel. With some small fixes.
All patches tested on x86_64 to not break anything.
Changes since v5:
- Squash calc keyid v2 with cmd_import patch.
- Add log_err messages to verify_hash_v2 and sign_hash_v2.
- Fix sign and hash generation error processing to show errors instead
of assert failures.
Changes since v4:
- Split conversion into more patches, as suggested by Mimi Zohar.
- Small fixes suggested by Mimi Zohar.
Changes since v3:
- As suggested by Mimi Zohar this is v3 splitted into several patches to
simplify review. No code changes.
Changes since v2:
- Just rebase over newer commits.
Changes since v1:
- More key neutral code in calc_keyid_v1().
- Fix uninitialized sigsize for EVP_PKEY_sign().
- Fix memory leaks for openssl types.
Vitaly Chikunov (11):
ima-evm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE
ima-evm-utils: Convert read_pub_key to EVP_PKEY API
ima-evm-utils: Convert read_priv_key to EVP_PKEY API
ima-evm-utils: Convert cmd_import and calc keyid v2 to EVP_PKEY API
ima-evm-utils: Start converting find_keyid to EVP_PKEY API
ima-evm-utils: Convert verify_hash_v2 to EVP_PKEY API
ima-evm-utils: Replace find_keyid with find_keyid_pkey
ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API
ima-evm-utils: Replace calc_keyid_v2 with calc_pkeyid_v2
ima-evm-utils: Remove RSA_ASN1_templates
ima-evm-utils: Pass status codes from sign and hash functions to the
callers
src/evmctl.c | 43 +++++----
src/imaevm.h | 4 +-
src/libimaevm.c | 277 +++++++++++++++++++++++++++-----------------------------
3 files changed, 158 insertions(+), 166 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v6 01/11] ima-evm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
@ 2019-06-20 7:12 ` Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 02/11] ima-evm-utils: Convert read_pub_key to EVP_PKEY API Vitaly Chikunov
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Fix off-by-one error of the output buffer passed to sign_hash().
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/evmctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 15a7226..03f41fe 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -510,7 +510,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
static int sign_evm(const char *file, const char *key)
{
unsigned char hash[MAX_DIGEST_SIZE];
- unsigned char sig[MAX_SIGNATURE_SIZE];
+ unsigned char sig[MAX_SIGNATURE_SIZE + 1];
int len, err;
len = calc_evm_hash(file, hash);
@@ -519,7 +519,7 @@ static int sign_evm(const char *file, const char *key)
return len;
len = sign_hash(params.hash_algo, hash, len, key, NULL, sig + 1);
- assert(len < sizeof(sig));
+ assert(len <= MAX_SIGNATURE_SIZE);
if (len <= 1)
return len;
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 02/11] ima-evm-utils: Convert read_pub_key to EVP_PKEY API
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 01/11] ima-evm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE Vitaly Chikunov
@ 2019-06-20 7:12 ` Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 03/11] ima-evm-utils: Convert read_priv_key " Vitaly Chikunov
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Introduce read_pub_pkey() to read keys using EVP_PKEY, and change
read_pub_key() to be wrapper for it.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/imaevm.h | 1 +
src/libimaevm.c | 33 ++++++++++++++++++++++-----------
2 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/src/imaevm.h b/src/imaevm.h
index c81bf21..6d5eabd 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -216,6 +216,7 @@ int get_filesize(const char *filename);
int ima_calc_hash(const char *file, uint8_t *hash);
int 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);
void calc_keyid_v1(uint8_t *keyid, char *str, const unsigned char *pkey, int len);
void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 3a9ab63..da0f422 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -355,10 +355,9 @@ int ima_calc_hash(const char *file, uint8_t *hash)
return mdlen;
}
-RSA *read_pub_key(const char *keyfile, int x509)
+EVP_PKEY *read_pub_pkey(const char *keyfile, int x509)
{
FILE *fp;
- RSA *key = NULL;
X509 *crt = NULL;
EVP_PKEY *pkey = NULL;
@@ -375,24 +374,36 @@ RSA *read_pub_key(const char *keyfile, int x509)
goto out;
}
pkey = X509_extract_key(crt);
+ X509_free(crt);
if (!pkey) {
log_err("X509_extract_key() failed\n");
goto out;
}
- key = EVP_PKEY_get1_RSA(pkey);
} else {
- key = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
+ pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
+ if (!pkey)
+ log_err("PEM_read_PUBKEY() failed\n");
}
- if (!key)
- log_err("PEM_read_RSA_PUBKEY() failed\n");
-
out:
- if (pkey)
- EVP_PKEY_free(pkey);
- if (crt)
- X509_free(crt);
fclose(fp);
+ return pkey;
+}
+
+RSA *read_pub_key(const char *keyfile, int x509)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+
+ pkey = read_pub_pkey(keyfile, x509);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key) {
+ log_err("read_pub_key: unsupported key type\n");
+ return NULL;
+ }
return key;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 03/11] ima-evm-utils: Convert read_priv_key to EVP_PKEY API
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 01/11] ima-evm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 02/11] ima-evm-utils: Convert read_pub_key to EVP_PKEY API Vitaly Chikunov
@ 2019-06-20 7:12 ` Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 04/11] ima-evm-utils: Convert cmd_import and calc keyid v2 " Vitaly Chikunov
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Introduce read_priv_pkey() to read keys using EVP_PKEY, and change
read_priv_key() to be wrapper for it.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/libimaevm.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index da0f422..23fa804 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -753,10 +753,10 @@ void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key)
free(pkey);
}
-static RSA *read_priv_key(const char *keyfile, const char *keypass)
+static EVP_PKEY *read_priv_pkey(const char *keyfile, const char *keypass)
{
FILE *fp;
- RSA *key;
+ EVP_PKEY *pkey;
fp = fopen(keyfile, "r");
if (!fp) {
@@ -764,15 +764,32 @@ static RSA *read_priv_key(const char *keyfile, const char *keypass)
return NULL;
}
ERR_load_crypto_strings();
- key = PEM_read_RSAPrivateKey(fp, NULL, NULL, (void *)keypass);
- if (!key) {
+ pkey = PEM_read_PrivateKey(fp, NULL, NULL, (void *)keypass);
+ if (!pkey) {
char str[256];
ERR_error_string(ERR_get_error(), str);
- log_err("PEM_read_RSAPrivateKey() failed: %s\n", str);
+ log_err("PEM_read_PrivateKey() failed: %s\n", str);
}
fclose(fp);
+ return pkey;
+}
+
+static RSA *read_priv_key(const char *keyfile, const char *keypass)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+
+ pkey = read_priv_pkey(keyfile, keypass);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (!key) {
+ log_err("read_priv_key: unsupported key type\n");
+ return NULL;
+ }
return key;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 04/11] ima-evm-utils: Convert cmd_import and calc keyid v2 to EVP_PKEY API
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (2 preceding siblings ...)
2019-06-20 7:12 ` [PATCH v6 03/11] ima-evm-utils: Convert read_priv_key " Vitaly Chikunov
@ 2019-06-20 7:12 ` Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 05/11] ima-evm-utils: Start converting find_keyid " Vitaly Chikunov
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Introduce calc_pkeyid_v2() (which accepts EVP_PKEY) to replace
calc_keyid_v2() (which accepts RSA) in the future and use it in
cmd_import().
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/evmctl.c | 25 +++++++++++++++----------
src/imaevm.h | 1 +
src/libimaevm.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 03f41fe..224cb1f 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -891,7 +891,6 @@ static int cmd_import(struct command *cmd)
int id, len, err = 0;
char name[20];
uint8_t keyid[8];
- RSA *key;
inkey = g_argv[optind++];
if (!inkey) {
@@ -925,18 +924,26 @@ static int cmd_import(struct command *cmd)
}
}
- key = read_pub_key(inkey, params.x509);
- if (!key)
- return 1;
-
if (params.x509) {
+ EVP_PKEY *pkey = read_pub_pkey(inkey, params.x509);
+
+ if (!pkey)
+ return 1;
pub = file2bin(inkey, NULL, &len);
- if (!pub)
- goto out;
- calc_keyid_v2((uint32_t *)keyid, name, key);
+ if (!pub) {
+ EVP_PKEY_free(pkey);
+ return 1;
+ }
+ calc_pkeyid_v2((uint32_t *)keyid, name, pkey);
+ EVP_PKEY_free(pkey);
} else {
+ RSA *key = read_pub_key(inkey, params.x509);
+
+ if (!key)
+ return 1;
len = key2bin(key, pub);
calc_keyid_v1(keyid, name, pub, len);
+ RSA_free(key);
}
log_info("Importing public key %s from file %s into keyring %d\n", name, inkey, id);
@@ -951,8 +958,6 @@ static int cmd_import(struct command *cmd)
}
if (params.x509)
free(pub);
-out:
- RSA_free(key);
return err;
}
diff --git a/src/imaevm.h b/src/imaevm.h
index 6d5eabd..48d2663 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -220,6 +220,7 @@ EVP_PKEY *read_pub_pkey(const char *keyfile, int x509);
void calc_keyid_v1(uint8_t *keyid, char *str, const unsigned char *pkey, int len);
void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key);
+void calc_pkeyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey);
int key2bin(RSA *key, unsigned char *pub);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 23fa804..707b2e9 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -753,6 +753,36 @@ void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key)
free(pkey);
}
+/*
+ * Calculate keyid of the public_key part of EVP_PKEY
+ */
+void calc_pkeyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey)
+{
+ X509_PUBKEY *pk = NULL;
+ const unsigned char *public_key = NULL;
+ int len;
+
+ /* This is more generic than i2d_PublicKey() */
+ if (X509_PUBKEY_set(&pk, pkey) &&
+ X509_PUBKEY_get0_param(NULL, &public_key, &len, NULL, pk)) {
+ uint8_t sha1[SHA_DIGEST_LENGTH];
+
+ SHA1(public_key, len, sha1);
+ /* sha1[12 - 19] is exactly keyid from gpg file */
+ memcpy(keyid, sha1 + 16, 4);
+ } else
+ *keyid = 0;
+
+ log_debug("keyid: ");
+ log_debug_dump(keyid, 4);
+ sprintf(str, "%x", __be32_to_cpup(keyid));
+
+ if (params.verbose > LOG_INFO)
+ log_info("keyid: %s\n", str);
+
+ X509_PUBKEY_free(pk);
+}
+
static EVP_PKEY *read_priv_pkey(const char *keyfile, const char *keypass)
{
FILE *fp;
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 05/11] ima-evm-utils: Start converting find_keyid to EVP_PKEY API
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (3 preceding siblings ...)
2019-06-20 7:12 ` [PATCH v6 04/11] ima-evm-utils: Convert cmd_import and calc keyid v2 " Vitaly Chikunov
@ 2019-06-20 7:12 ` Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 06/11] ima-evm-utils: Convert verify_hash_v2 " Vitaly Chikunov
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
New find_keyid_pkey() accepts EVP_PKEY. Old find_keyid() calls
find_keyid_pkey(), but still return RSA key.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/libimaevm.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 707b2e9..ae18005 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -452,11 +452,11 @@ struct public_key_entry {
struct public_key_entry *next;
uint32_t keyid;
char name[9];
- RSA *key;
+ EVP_PKEY *key;
};
static struct public_key_entry *public_keys = NULL;
-static RSA *find_keyid(uint32_t keyid)
+static EVP_PKEY *find_keyid_pkey(uint32_t keyid)
{
struct public_key_entry *entry;
@@ -467,6 +467,22 @@ static RSA *find_keyid(uint32_t keyid)
return NULL;
}
+static RSA *find_keyid(uint32_t keyid)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+
+ pkey = find_keyid_pkey(keyid);
+ if (!pkey)
+ return NULL;
+ key = EVP_PKEY_get0_RSA(pkey);
+ if (!key) {
+ log_err("find_keyid: unsupported key type\n");
+ return NULL;
+ }
+ return key;
+}
+
void init_public_keys(const char *keyfiles)
{
struct public_key_entry *entry;
@@ -489,13 +505,13 @@ void init_public_keys(const char *keyfiles)
break;
}
- entry->key = read_pub_key(keyfile, 1);
+ entry->key = read_pub_pkey(keyfile, 1);
if (!entry->key) {
free(entry);
continue;
}
- calc_keyid_v2(&entry->keyid, entry->name, entry->key);
+ calc_pkeyid_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;
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 06/11] ima-evm-utils: Convert verify_hash_v2 to EVP_PKEY API
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (4 preceding siblings ...)
2019-06-20 7:12 ` [PATCH v6 05/11] ima-evm-utils: Start converting find_keyid " Vitaly Chikunov
@ 2019-06-20 7:12 ` Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 07/11] ima-evm-utils: Replace find_keyid with find_keyid_pkey Vitaly Chikunov
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:12 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Rely on OpenSSL API to verify v2 signatures instead of manual PKCS1
decoding.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/libimaevm.c | 74 +++++++++++++++++++++++++++++----------------------------
1 file changed, 38 insertions(+), 36 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index ae18005..c24c67f 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -519,14 +519,17 @@ void init_public_keys(const char *keyfiles)
}
}
+/*
+ * Return: 0 verification good, 1 verification bad, -1 error.
+ */
int verify_hash_v2(const char *file, const unsigned char *hash, int size,
unsigned char *sig, int siglen, const char *keyfile)
{
- int err, len;
- unsigned char out[1024];
- RSA *key;
+ int ret = -1;
+ EVP_PKEY *pkey;
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
- const struct RSA_ASN1_template *asn1;
+ EVP_PKEY_CTX *ctx;
+ const EVP_MD *md;
if (params.verbose > LOG_INFO) {
log_info("hash: ");
@@ -534,45 +537,44 @@ int verify_hash_v2(const char *file, const unsigned char *hash, int size,
}
if (public_keys) {
- key = find_keyid(hdr->keyid);
- if (!key) {
+ pkey = find_keyid_pkey(hdr->keyid);
+ if (!pkey) {
log_err("%s: unknown keyid: %x\n", file,
__be32_to_cpup(&hdr->keyid));
return -1;
}
} else {
- key = read_pub_key(keyfile, 1);
- if (!key)
- return 1;
- }
-
-
- err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr),
- out, key, RSA_PKCS1_PADDING);
- if (err < 0) {
- log_err("%s: RSA_public_decrypt() failed: %d\n", file, err);
- return 1;
- }
-
- len = err;
-
- asn1 = &RSA_ASN1_templates[hdr->hash_algo];
-
- if (len < asn1->size || memcmp(out, asn1->data, asn1->size)) {
- log_err("%s: verification failed: %d (asn1 mismatch)\n",
- file, err);
- return -1;
- }
-
- len -= asn1->size;
-
- if (len != size || memcmp(out + asn1->size, hash, len)) {
- log_err("%s: verification failed: %d (digest mismatch)\n",
- file, err);
- return -1;
+ pkey = read_pub_pkey(keyfile, 1);
+ if (!pkey)
+ return -1;
}
- return 0;
+ if (!(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
+ goto err;
+ if (!EVP_PKEY_verify_init(ctx))
+ goto err;
+ if (!(md = EVP_get_digestbyname(params.hash_algo)))
+ goto err;
+ if (!EVP_PKEY_CTX_set_signature_md(ctx, md))
+ goto err;
+ ret = EVP_PKEY_verify(ctx, sig + sizeof(*hdr),
+ siglen - sizeof(*hdr), hash, size);
+ if (ret == 1)
+ ret = 0;
+ else if (ret == 0) {
+ log_err("%s: verification failed: %d (%s)\n",
+ file, ret, ERR_reason_error_string(ERR_get_error()));
+ ret = 1;
+ }
+err:
+ if (ret < 0 || ret > 1) {
+ log_err("%s: verification failed: %d (%s)\n",
+ file, ret, ERR_reason_error_string(ERR_peek_error()));
+ ret = -1;
+ }
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ return ret;
}
int get_hash_algo(const char *algo)
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 07/11] ima-evm-utils: Replace find_keyid with find_keyid_pkey
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (5 preceding siblings ...)
2019-06-20 7:12 ` [PATCH v6 06/11] ima-evm-utils: Convert verify_hash_v2 " Vitaly Chikunov
@ 2019-06-20 7:13 ` Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 08/11] ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API Vitaly Chikunov
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:13 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Finish conversion of find_keyid to EVP_PKEY API. After verify_hash_v2()
is switched to EVP_PKEY API (in previous commit) old RSA-specific
find_keyid() does not needed anymore and can be replaced with
find_keyid_pkey().
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/libimaevm.c | 20 ++------------------
1 file changed, 2 insertions(+), 18 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index c24c67f..d8223e0 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -456,7 +456,7 @@ struct public_key_entry {
};
static struct public_key_entry *public_keys = NULL;
-static EVP_PKEY *find_keyid_pkey(uint32_t keyid)
+static EVP_PKEY *find_keyid(uint32_t keyid)
{
struct public_key_entry *entry;
@@ -467,22 +467,6 @@ static EVP_PKEY *find_keyid_pkey(uint32_t keyid)
return NULL;
}
-static RSA *find_keyid(uint32_t keyid)
-{
- EVP_PKEY *pkey;
- RSA *key;
-
- pkey = find_keyid_pkey(keyid);
- if (!pkey)
- return NULL;
- key = EVP_PKEY_get0_RSA(pkey);
- if (!key) {
- log_err("find_keyid: unsupported key type\n");
- return NULL;
- }
- return key;
-}
-
void init_public_keys(const char *keyfiles)
{
struct public_key_entry *entry;
@@ -537,7 +521,7 @@ int verify_hash_v2(const char *file, const unsigned char *hash, int size,
}
if (public_keys) {
- pkey = find_keyid_pkey(hdr->keyid);
+ pkey = find_keyid(hdr->keyid);
if (!pkey) {
log_err("%s: unknown keyid: %x\n", file,
__be32_to_cpup(&hdr->keyid));
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 08/11] ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (6 preceding siblings ...)
2019-06-20 7:13 ` [PATCH v6 07/11] ima-evm-utils: Replace find_keyid with find_keyid_pkey Vitaly Chikunov
@ 2019-06-20 7:13 ` Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 09/11] ima-evm-utils: Replace calc_keyid_v2 with calc_pkeyid_v2 Vitaly Chikunov
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:13 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Convert sign_hash_v2() to use more generic EVP_PKEY API instead of RSA
API. This enables generation of more signatures out of the box, such as
EC-RDSA (GOST) and any other that OpenSSL supports. This conversion also
fixes generation of MD4 signatures, because it didn't have proper
RSA_ASN1_template.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/libimaevm.c | 54 ++++++++++++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 24 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index d8223e0..0d3f49f 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -916,14 +916,19 @@ out:
return len;
}
+/*
+ * @sig is assumed to be of MAX_SIGNATURE_SIZE size
+ * Return: -1 signing error, >0 length of signature
+ */
int sign_hash_v2(const char *algo, const unsigned char *hash, int size, const char *keyfile, unsigned char *sig)
{
struct signature_v2_hdr *hdr;
int len = -1;
- RSA *key;
+ EVP_PKEY *pkey;
char name[20];
- unsigned char *buf;
- const struct RSA_ASN1_template *asn1;
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md;
+ size_t sigsize;
if (!hash) {
log_err("sign_hash_v2: hash is null\n");
@@ -948,8 +953,8 @@ int sign_hash_v2(const char *algo, const unsigned char *hash, int size, const ch
log_info("hash: ");
log_dump(hash, size);
- key = read_priv_key(keyfile, params.keypass);
- if (!key)
+ pkey = read_priv_pkey(keyfile, params.keypass);
+ if (!pkey)
return -1;
hdr = (struct signature_v2_hdr *)sig;
@@ -957,31 +962,32 @@ int sign_hash_v2(const char *algo, const unsigned char *hash, int size, const ch
hdr->hash_algo = get_hash_algo(algo);
- calc_keyid_v2(&hdr->keyid, name, key);
+ calc_pkeyid_v2(&hdr->keyid, name, pkey);
- asn1 = &RSA_ASN1_templates[hdr->hash_algo];
-
- buf = malloc(size + asn1->size);
- if (!buf)
- goto out;
-
- memcpy(buf, asn1->data, asn1->size);
- memcpy(buf + asn1->size, hash, size);
- len = RSA_private_encrypt(size + asn1->size, buf, hdr->sig,
- key, RSA_PKCS1_PADDING);
- if (len < 0) {
- log_err("RSA_private_encrypt() failed: %d\n", len);
- goto out;
- }
+ if (!(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
+ goto err;
+ if (!EVP_PKEY_sign_init(ctx))
+ goto err;
+ if (!(md = EVP_get_digestbyname(params.hash_algo)))
+ goto err;
+ if (!EVP_PKEY_CTX_set_signature_md(ctx, md))
+ goto err;
+ sigsize = MAX_SIGNATURE_SIZE - sizeof(struct signature_v2_hdr);
+ if (!EVP_PKEY_sign(ctx, hdr->sig, &sigsize, hash, size))
+ goto err;
+ len = (int)sigsize;
/* we add bit length of the signature to make it gnupg compatible */
hdr->sig_size = __cpu_to_be16(len);
len += sizeof(*hdr);
log_info("evm/ima signature: %d bytes\n", len);
-out:
- if (buf)
- free(buf);
- RSA_free(key);
+
+err:
+ if (len == -1)
+ log_err("sign_hash_v2: signing failed: (%s)\n",
+ ERR_reason_error_string(ERR_peek_error()));
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
return len;
}
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 09/11] ima-evm-utils: Replace calc_keyid_v2 with calc_pkeyid_v2
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (7 preceding siblings ...)
2019-06-20 7:13 ` [PATCH v6 08/11] ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API Vitaly Chikunov
@ 2019-06-20 7:13 ` Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 10/11] ima-evm-utils: Remove RSA_ASN1_templates Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 11/11] ima-evm-utils: Pass status codes from sign and hash functions to the callers Vitaly Chikunov
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:13 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Finish conversion of calc keyid v2 to EVP_PKEY API. After sign_hash_v2()
is switched to EVP_PKEY API (in previous commit), older RSA-specific
calc_keyid_v2() does not needed anymore and can be replaced with
calc_pkeyid_v2().
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/evmctl.c | 2 +-
src/imaevm.h | 3 +--
src/libimaevm.c | 28 +++-------------------------
3 files changed, 5 insertions(+), 28 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 224cb1f..ded18c6 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -934,7 +934,7 @@ static int cmd_import(struct command *cmd)
EVP_PKEY_free(pkey);
return 1;
}
- calc_pkeyid_v2((uint32_t *)keyid, name, pkey);
+ calc_keyid_v2((uint32_t *)keyid, name, pkey);
EVP_PKEY_free(pkey);
} else {
RSA *key = read_pub_key(inkey, params.x509);
diff --git a/src/imaevm.h b/src/imaevm.h
index 48d2663..9af43a2 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -219,8 +219,7 @@ RSA *read_pub_key(const char *keyfile, int x509);
EVP_PKEY *read_pub_pkey(const char *keyfile, int x509);
void calc_keyid_v1(uint8_t *keyid, char *str, const unsigned char *pkey, int len);
-void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key);
-void calc_pkeyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey);
+void calc_keyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey);
int key2bin(RSA *key, unsigned char *pub);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 0d3f49f..4e268f8 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -495,7 +495,7 @@ void init_public_keys(const char *keyfiles)
continue;
}
- calc_pkeyid_v2(&entry->keyid, entry->name, entry->key);
+ 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;
@@ -733,32 +733,10 @@ void calc_keyid_v1(uint8_t *keyid, char *str, const unsigned char *pkey, int len
log_info("keyid-v1: %s\n", str);
}
-void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key)
-{
- uint8_t sha1[SHA_DIGEST_LENGTH];
- unsigned char *pkey = NULL;
- int len;
-
- len = i2d_RSAPublicKey(key, &pkey);
-
- SHA1(pkey, len, sha1);
-
- /* sha1[12 - 19] is exactly keyid from gpg file */
- memcpy(keyid, sha1 + 16, 4);
- log_debug("keyid: ");
- log_debug_dump(keyid, 4);
- sprintf(str, "%x", __be32_to_cpup(keyid));
-
- if (params.verbose > LOG_INFO)
- log_info("keyid: %s\n", str);
-
- free(pkey);
-}
-
/*
* Calculate keyid of the public_key part of EVP_PKEY
*/
-void calc_pkeyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey)
+void calc_keyid_v2(uint32_t *keyid, char *str, EVP_PKEY *pkey)
{
X509_PUBKEY *pk = NULL;
const unsigned char *public_key = NULL;
@@ -962,7 +940,7 @@ int sign_hash_v2(const char *algo, const unsigned char *hash, int size, const ch
hdr->hash_algo = get_hash_algo(algo);
- calc_pkeyid_v2(&hdr->keyid, name, pkey);
+ calc_keyid_v2(&hdr->keyid, name, pkey);
if (!(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
goto err;
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 10/11] ima-evm-utils: Remove RSA_ASN1_templates
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (8 preceding siblings ...)
2019-06-20 7:13 ` [PATCH v6 09/11] ima-evm-utils: Replace calc_keyid_v2 with calc_pkeyid_v2 Vitaly Chikunov
@ 2019-06-20 7:13 ` Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 11/11] ima-evm-utils: Pass status codes from sign and hash functions to the callers Vitaly Chikunov
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:13 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
RSA_ASN1_templates[] are not needed anymore, because we switched to the
generic EVP_PKEY OpenSSL API to generate v2 signatures instead of
constructing PKCS1 ourselves.
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/imaevm.h | 1 -
src/libimaevm.c | 57 ---------------------------------------------------------
2 files changed, 58 deletions(-)
diff --git a/src/imaevm.h b/src/imaevm.h
index 9af43a2..dc81a3a 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -207,7 +207,6 @@ struct RSA_ASN1_template {
#define NUM_PCRS 20
#define DEFAULT_PCR 10
-extern const struct RSA_ASN1_template RSA_ASN1_templates[PKEY_HASH__LAST];
extern struct libevm_params params;
void do_dump(FILE *fp, const void *ptr, int len, bool cr);
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 4e268f8..9e90d07 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -81,63 +81,6 @@ const char *const pkey_hash_algo_kern[PKEY_HASH__LAST] = {
[PKEY_HASH_STREEBOG_512] = "streebog512",
};
-/*
- * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
- */
-static const uint8_t RSA_digest_info_MD5[] = {
- 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */
- 0x05, 0x00, 0x04, 0x10
-};
-
-static const uint8_t RSA_digest_info_SHA1[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2B, 0x0E, 0x03, 0x02, 0x1A,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const uint8_t RSA_digest_info_RIPE_MD_160[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2B, 0x24, 0x03, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const uint8_t RSA_digest_info_SHA224[] = {
- 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
- 0x05, 0x00, 0x04, 0x1C
-};
-
-static const uint8_t RSA_digest_info_SHA256[] = {
- 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x20
-};
-
-static const uint8_t RSA_digest_info_SHA384[] = {
- 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
- 0x05, 0x00, 0x04, 0x30
-};
-
-static const uint8_t RSA_digest_info_SHA512[] = {
- 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
- 0x05, 0x00, 0x04, 0x40
-};
-
-const struct RSA_ASN1_template RSA_ASN1_templates[PKEY_HASH__LAST] = {
-#define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) }
- [PKEY_HASH_MD5] = _(MD5),
- [PKEY_HASH_SHA1] = _(SHA1),
- [PKEY_HASH_RIPE_MD_160] = _(RIPE_MD_160),
- [PKEY_HASH_SHA256] = _(SHA256),
- [PKEY_HASH_SHA384] = _(SHA384),
- [PKEY_HASH_SHA512] = _(SHA512),
- [PKEY_HASH_SHA224] = _(SHA224),
-#undef _
-};
-
struct libevm_params params = {
.verbose = LOG_INFO - 1,
.x509 = 1,
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v6 11/11] ima-evm-utils: Pass status codes from sign and hash functions to the callers
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
` (9 preceding siblings ...)
2019-06-20 7:13 ` [PATCH v6 10/11] ima-evm-utils: Remove RSA_ASN1_templates Vitaly Chikunov
@ 2019-06-20 7:13 ` Vitaly Chikunov
10 siblings, 0 replies; 12+ messages in thread
From: Vitaly Chikunov @ 2019-06-20 7:13 UTC (permalink / raw)
To: Mimi Zohar, Dmitry Kasatkin, linux-integrity
Move sign_hash()/ima_calc_hash()/calc_evm_hmac()/calc_evm_hash() status
checking before assert()'ing of their return values, so it can be passed
to the upper level callers. Especially useful for showing errors.
Fixes: 1d9c279279 ("Define hash and sig buffer sizes and add asserts")
Fixes: 9643544701 ("Fix hash buffer overflow in verify_evm and hmac_evm")
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
---
src/evmctl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index ded18c6..63ae1a6 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -514,14 +514,14 @@ static int sign_evm(const char *file, const char *key)
int len, err;
len = calc_evm_hash(file, hash);
- assert(len <= sizeof(hash));
if (len <= 1)
return len;
+ assert(len <= sizeof(hash));
len = sign_hash(params.hash_algo, hash, len, key, NULL, sig + 1);
- assert(len <= MAX_SIGNATURE_SIZE);
if (len <= 1)
return len;
+ assert(len <= MAX_SIGNATURE_SIZE);
/* add header */
len++;
@@ -563,9 +563,9 @@ static int hash_ima(const char *file)
}
len = ima_calc_hash(file, hash + offset);
- assert(len + offset <= sizeof(hash));
if (len <= 1)
return len;
+ assert(len + offset <= sizeof(hash));
len += offset;
@@ -593,14 +593,14 @@ static int sign_ima(const char *file, const char *key)
int len, err;
len = ima_calc_hash(file, hash);
- assert(len <= sizeof(hash));
if (len <= 1)
return len;
+ assert(len <= sizeof(hash));
len = sign_hash(params.hash_algo, hash, len, key, NULL, sig + 1);
- assert(len < sizeof(sig));
if (len <= 1)
return len;
+ assert(len < sizeof(sig));
/* add header */
len++;
@@ -724,9 +724,9 @@ static int cmd_sign_hash(struct command *cmd)
hex2bin(hash, line, hashlen / 2);
siglen = sign_hash(params.hash_algo, hash, hashlen/2,
key, NULL, sig + 1);
- assert(siglen < sizeof(sig));
if (siglen <= 1)
return siglen;
+ assert(siglen < sizeof(sig));
fwrite(line, len, 1, stdout);
fprintf(stdout, " ");
@@ -778,9 +778,9 @@ static int verify_evm(const char *file)
int len;
mdlen = calc_evm_hash(file, hash);
- assert(mdlen <= sizeof(hash));
if (mdlen <= 1)
return mdlen;
+ assert(mdlen <= sizeof(hash));
len = lgetxattr(file, xattr_evm, sig, sizeof(sig));
if (len < 0) {
@@ -1160,9 +1160,9 @@ static int hmac_evm(const char *file, const char *key)
int len, err;
len = calc_evm_hmac(file, key, hash);
- assert(len <= sizeof(hash));
if (len <= 1)
return len;
+ assert(len <= sizeof(hash));
log_info("hmac: ");
log_dump(hash, len);
--
2.11.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2019-06-20 7:14 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-20 7:12 [PATCH v6 00/11] ima-evm-utils: Convert v2 signatures from RSA to EVP_PKEY API Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 01/11] ima-evm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 02/11] ima-evm-utils: Convert read_pub_key to EVP_PKEY API Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 03/11] ima-evm-utils: Convert read_priv_key " Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 04/11] ima-evm-utils: Convert cmd_import and calc keyid v2 " Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 05/11] ima-evm-utils: Start converting find_keyid " Vitaly Chikunov
2019-06-20 7:12 ` [PATCH v6 06/11] ima-evm-utils: Convert verify_hash_v2 " Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 07/11] ima-evm-utils: Replace find_keyid with find_keyid_pkey Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 08/11] ima-evm-utils: Convert sign_hash_v2 to EVP_PKEY API Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 09/11] ima-evm-utils: Replace calc_keyid_v2 with calc_pkeyid_v2 Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 10/11] ima-evm-utils: Remove RSA_ASN1_templates Vitaly Chikunov
2019-06-20 7:13 ` [PATCH v6 11/11] ima-evm-utils: Pass status codes from sign and hash functions to the callers Vitaly Chikunov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).