ima-avm-utils: Convert sign v2 from RSA to EVP_PKEY API
v4 cover ima-avm-utils: Convert sign v2 from RSA to EVP_PKEY API
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 (5):
ima-avm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE
ima-avm-utils: Change read_pub_key to use EVP_PKEY API
ima-avm-utils: Change read_priv_key to use EVP_PKEY API
ima-evm-utils: Convert sign v2 from RSA to EVP_PKEY API
ima-avm-utils: Remove RSA_ASN1_templates
src/evmctl.c | 29 +++--- src/imaevm.h | 4 +- src/libimaevm.c | 269 ++++++++++++++++++++++++++------------------------------ 3 files changed, 146 insertions(+), 156 deletions(-)
Signature · 1 line
2.11.0
PATCH v4 1/5 ima-avm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE
Fix off-by-one error of the output buffer passed to sign_hash().
--- src/evmctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
src/evmctl.c +2 -2
@@ -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;
Signature · 1 line
2.11.0
Mimi Zohar
maintainerRe: [PATCH v4 1/5] ima-avm-utils: Make sure sig buffer is always MAX_SIGNATURE_SIZE
Quoted 21 lines · Vitaly Chikunov
Fix off-by-one error of the output buffer passed to
sign_hash().Signed-off-by Vitaly Chikunov <[email protected]>--- src/evmctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)src/evmctl.c +1
-1@@ -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);
src/evmctl.c static int sign_evm(const char *file, const char *key) · line 522
Quoted 5 lines
src/evmctl.c +1
-1@@ -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 );
Should this be "<="?
Mimi
Quoted 3 lines
src/evmctl.c +0
-0if (len <=1 )return len;
PATCH v4 2/5 ima-avm-utils: Change read_pub_key to use EVP_PKEY API
In reply to Vitaly ChikunovIntroduce read_pub_pkey() to read keys using EVP_PKEY, and change read_pub_key() to be wrapper for it.
--- src/imaevm.h | 1 + src/libimaevm.c | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-)
src/imaevm.h +1 -0
@@ -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);
src/libimaevm.c +22 -11
@@ -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; }
Signature · 1 line
2.11.0
PATCH v4 3/5 ima-avm-utils: Change read_priv_key to use EVP_PKEY API
In reply to Vitaly ChikunovIntroduce read_priv_pkey() to read keys using EVP_PKEY, and change read_priv_key() to be wrapper for it.
--- src/libimaevm.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-)
src/libimaevm.c +27 -5
@@ -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 *key; fp =fopen (keyfile,"r" );if (!fp) {
@@ -764,18 +764,40 @@ 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); + key =PEM_read_PrivateKey (fp,NULL ,NULL , (void *)keypass);if (!key) {char str[256 ]; -ERR_error_string (ERR_get_error (), str); -log_err ("PEM_read_RSAPrivateKey() failed: %s\n" , str); +ERR_error_string (ERR_peek_error (), str); +log_err ("PEM_read_PrivateKey() failed: %s\n" , str); +#ifdef USE_FPRINTF +ERR_print_errors_fp (stderr); +#else +ERR_clear_error (); +#endif }fclose (fp);return key; } +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 ("sign_hash_v1: unsupported key type\n" ); +return NULL ; + } +return key; +} +static int get_hash_algo_v1 (const char *algo) {
Signature · 1 line
2.11.0
Mimi Zohar
maintainerRe: [PATCH v4 3/5] ima-avm-utils: Change read_priv_key to use EVP_PKEY API
Quoted 13 lines · Vitaly Chikunov
Introduce
read_priv_pkey()to read keys usingEVP_PKEY, and changeread_priv_key()to be wrapper for it.Signed-off-by Vitaly Chikunov <[email protected]>--- src/libimaevm.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-)src/libimaevm.c +0
-0
src/libimaevm.c void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key) · line 759
Quoted 9 lines
src/libimaevm.c +2
-2@@ -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 *key;
In read_pub_pkey() EVP_PKEY is named pkey, not key.
Quoted 11 lines
src/libimaevm.c +1
-1fp =fopen (keyfile,"r" );if (!fp) {@@ -764,18 +764,40 @@ 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); + key =PEM_read_PrivateKey (fp,NULL ,NULL , (void *)keypass);if (!key) {char str[256 ];
src/libimaevm.c static RSA *read_priv_key(const char *keyfile, const char *keypass) · line 777
Quoted 10 lines
src/libimaevm.c +7
-2-ERR_error_string (ERR_get_error (), str); -log_err ("PEM_read_RSAPrivateKey() failed: %s\n" , str); +ERR_error_string (ERR_peek_error (), str); +log_err ("PEM_read_PrivateKey() failed: %s\n" , str); +#ifdef USE_FPRINTF +ERR_print_errors_fp (stderr); +#else +ERR_clear_error (); +#endif
Why is this additional print needed? Are you expecting multiple errors? By calling both log_err() and ERR_print_errors_fp() won't the same error message be duplicated? If calling "ERR_print_errors_fp()" is indeed needed, please make this change as a separate patch, with an appropriate patch description.
Quoted 10 lines
src/libimaevm.c +4
-0}fclose (fp);return key; } +static RSA *read_priv_key (const char *keyfile,const char *keypass) +{ +EVP_PKEY *pkey; +RSA *key;
src/libimaevm.c static RSA *read_priv_key(const char *keyfile, const char *keypass) · line 797
Quoted 10 lines
src/libimaevm.c +10
-0+ + pkey =read_priv_pkey (keyfile, keypass); +if (!pkey) +return NULL ; + key =EVP_PKEY_get1_RSA (pkey); +EVP_PKEY_free (pkey); +if (!key) { +log_err ("sign_hash_v1: unsupported key type\n" ); +return NULL ; + }
At least at this point in the patch series, failing to get the private key isn't limited to sign_hash_v1. Perhaps that might be true later.
Mimi
Quoted 6 lines
src/libimaevm.c +3
-0+return key; +} +static int get_hash_algo_v1 (const char *algo) {
PATCH v4 4/5 ima-evm-utils: Convert sign v2 from RSA to EVP_PKEY API
In reply to Vitaly ChikunovConvert sign_v2 and related to using more generic EVP_PKEY API instead of RSA API. This enables more signatures to work out of the box.
--- src/evmctl.c | 25 ++++++---- src/imaevm.h | 2 +- src/libimaevm.c | 145 ++++++++++++++++++++++++++++++-------------------------- 3 files changed, 93 insertions(+), 79 deletions(-)
src/evmctl.c +15 -10
@@ -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_keyid_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; }
src/imaevm.h +1 -1
@@ -219,7 +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_keyid_v2 (uint32_t *keyid,char *str,EVP_PKEY *key);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);
src/libimaevm.c +77 -68
228 lines not on this page · raw message
Signature · 1 line
2.11.0
Mimi Zohar
maintainerRe: [PATCH v4 4/5] ima-evm-utils: Convert sign v2 from RSA to EVP_PKEY API
Quoted 2 lines · Vitaly Chikunov
Convert
sign_v2and related to using more genericEVP_PKEYAPI instead of RSA API. This enables more signatures to work out of the box.
Please elaborate on "enables more signatures to work out of the box", perhaps with example(s).
I like simple stories, where everything is laid out. Think of a patch set as a simple story, not a mystery, explaining how you go from point A to point B. Each patch in the series explains the next step.
The changes in cmd_import() are nice, straight forward, and easy to read. Other than the "calc_keyid_v2()" change from passing an RSA key to pkey key" dependency, this could be a separate patch. Please see if you could further break this patch up to simplify review.
Mimi
Re: [PATCH v4 4/5] ima-evm-utils: Convert sign v2 from RSA to EVP_PKEY API
Mimi,
Quoted 6 lines · Mimi Zohar
Quoted 2 lines · Vitaly Chikunov
Convert
sign_v2and related to using more genericEVP_PKEYAPI instead of RSA API. This enables more signatures to work out of the box.Please elaborate on "enables more signatures to work out of the box", perhaps with example(s).
Yes, message is split between next commit where it's mentioned that MD4 got fixed. I will also mention EC-RDSA. Basically, anything that OpenSSL supports will work.
Quoted 8 lines
I like simple stories, where everything is laid out. Think of a patch set as a simple story, not a mystery, explaining how you go from point A to point B. Each patch in the series explains the next step.
The changes in
cmd_import()are nice, straight forward, and easy to read. Other than the "calc_keyid_v2()" change from passing an RSA key to pkey key" dependency, this could be a separate patch. Please see if you could further break this patch up to simplify review.
I thought about splitting as much as possible, but didn't not find what to split more.
- If we add read_pub_pkey into cmd_import then we can not use old calc_keyid_v2 (which wants RSA).
- If we add new calc_keyid_v2 into cmd_import it would require calling read_pub_pkey (and have sign_hash_v2 updated too).
- We can not put cmd_import change before 'rsa to pkey' change, because calc_keyid_v2 is also used in new sign_hash_v2.
- We can not put cmd_import change after 'rsa to pkey' change, because cmd_import will fail for v2 signatures (which should use PKEY).
So I don't see how this is splittable.
Thanks,
Mimi Zohar
maintainerRe: [PATCH v4 4/5] ima-evm-utils: Convert sign v2 from RSA to EVP_PKEY API
Quoted 21 lines · Vitaly Chikunov
Quoted 8 lines
I like simple stories, where everything is laid out. Think of a patch set as a simple story, not a mystery, explaining how you go from point A to point B. Each patch in the series explains the next step.
The changes in
cmd_import()are nice, straight forward, and easy to read. Other than the "calc_keyid_v2()" change from passing an RSA key to pkey key" dependency, this could be a separate patch. Please see if you could further break this patch up to simplify review.I thought about splitting as much as possible, but didn't not find what to split more.
- If we add
read_pub_pkeyintocmd_importthen we can not use oldcalc_keyid_v2(which wants RSA).
- If we add newcalc_keyid_v2intocmd_importit would require callingread_pub_pkey(and havesign_hash_v2updated too).
- We can not putcmd_importchange before 'rsa to pkey' change, becausecalc_keyid_v2is also used in newsign_hash_v2.
- We can not putcmd_importchange after 'rsa to pkey' change, becausecmd_importwill fail for v2 signatures (which should use PKEY).
Quoted 1 line
So I don't see how this is splittable.
Perhaps it causes more patch churn, but there always is a way. In this case, there are a couple of ways. Instead of replacing "key" with "pkey":
- define pkey as an additional argument to calc_keyid_v2().
- define a new function named, for example, calc_keyid_v2_pkey().
Mimi
PATCH v4 5/5 ima-avm-utils: Remove RSA_ASN1_templates
In reply to Vitaly ChikunovRemove RSA_ASN1_templates[] as it does not needed anymore. OpenSSL sign is doing proper PKCS1 padding automatically (tested to be compatible with previous version, except for MD4). This also fixes bug with MD4 which produced wrong signature because of absence of the appropriate RSA_ASN1_template.
--- src/imaevm.h | 1 - src/libimaevm.c | 57 --------------------------------------------------------- 2 files changed, 58 deletions(-)
src/imaevm.h +0 -1
@@ -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);
src/libimaevm.c +0 -57
63 lines not on this page · raw message
Signature · 1 line
2.11.0
Mimi,
Sorry for the typo in ima-avm-utils instead of ima-evm-utils. Would you correct it if you going to apply the patches, or I can resend.
Thanks,
Quoted 26 lines · Vitaly Chikunov
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 incalc_keyid_v1().
- Fix uninitialized sigsize forEVP_PKEY_sign().
- Fix memory leaks for openssl types.Vitaly Chikunov (5):
ima-avm-utils: Make sure sig buffer is alwaysMAX_SIGNATURE_SIZE
ima-avm-utils: Changeread_pub_keyto useEVP_PKEYAPI
ima-avm-utils: Changeread_priv_keyto useEVP_PKEYAPI
ima-evm-utils: Convert sign v2 from RSA toEVP_PKEYAPI
ima-avm-utils: RemoveRSA_ASN1_templatessrc/evmctl.c | 29 +++--- src/imaevm.h | 4 +- src/libimaevm.c | 269 ++++++++++++++++++++++++++------------------------------ 3 files changed, 146 insertions(+), 156 deletions(-)Signature · 1 line
2.11.0