From a7a4e6c00f6873559c686faecee4a03910627e9a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Sep 2017 14:11:55 +0200 Subject: [PATCH 01/20] Add missing SHA224 RSA algorithms --- src/pkcs11/pkcs11.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 74b13c6894..8a03ab29c5 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -508,6 +508,8 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_SHA256_RSA_PKCS_PSS (0x43UL) #define CKM_SHA384_RSA_PKCS_PSS (0x44UL) #define CKM_SHA512_RSA_PKCS_PSS (0x45UL) +#define CKM_SHA224_RSA_PKCS (0x46UL) +#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) #define CKM_RC2_KEY_GEN (0x100UL) #define CKM_RC2_ECB (0x101UL) #define CKM_RC2_CBC (0x102UL) From 811a6b9bdabd68e7e30e0692c24ff40809ffb330 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Sep 2017 15:03:55 +0200 Subject: [PATCH 02/20] Fix wrong replacement in pkcs11-tool manual page --- doc/tools/pkcs11-tool.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 471b9b4d4d..45a0683fc4 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -116,7 +116,7 @@ - specification + specification Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1. From 6d37b6cf22712f7906fbc9d4163d00620adcfcf2 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Sep 2017 16:10:40 +0200 Subject: [PATCH 03/20] Add MGF and PSS_PARAMS definitions in PKCS#11 header file --- src/pkcs11/pkcs11.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 8a03ab29c5..ac8ae7212b 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -153,6 +153,8 @@ extern "C" { #define ck_mechanism_type_t CK_MECHANISM_TYPE +#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE + #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen @@ -478,6 +480,8 @@ struct ck_date typedef unsigned long ck_mechanism_type_t; +typedef unsigned long int ck_rsa_pkcs_mgf_type_t; + #define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) #define CKM_RSA_PKCS (1UL) #define CKM_RSA_9796 (2UL) @@ -757,6 +761,17 @@ typedef struct CK_ECDH1_DERIVE_PARAMS { unsigned char * pPublicData; } CK_ECDH1_DERIVE_PARAMS; +typedef struct CK_RSA_PKCS_PSS_PARAMS { + ck_mechanism_type_t hashAlg; + unsigned long mgf; + unsigned long sLen; +} CK_RSA_PKCS_PSS_PARAMS; + +#define CKG_MGF1_SHA1 (0x00000001UL) +#define CKG_MGF1_SHA224 (0x00000005UL) +#define CKG_MGF1_SHA256 (0x00000002UL) +#define CKG_MGF1_SHA384 (0x00000003UL) +#define CKG_MGF1_SHA512 (0x00000004UL) typedef unsigned long ck_rv_t; @@ -1294,6 +1309,8 @@ typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; +typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR; + typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; @@ -1364,6 +1381,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_mechanism_type_t +#undef ck_rsa_pkcs_mgf_type_t + #undef ck_mechanism #undef parameter #undef parameter_len From 89309a56b8f0a804caf123aae1a4bea013a7bd0b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Sep 2017 16:12:47 +0200 Subject: [PATCH 04/20] Inspect PSS signature parameters in pkcs11-spy --- src/pkcs11/pkcs11-display.c | 9 +++++++++ src/pkcs11/pkcs11-display.h | 1 + src/pkcs11/pkcs11-spy.c | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index a05a7f9376..753c05fa20 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -521,6 +521,14 @@ static enum_specs ck_mec_s[] = { { CKM_VENDOR_DEFINED , "CKM_VENDOR_DEFINED " } }; +static enum_specs ck_mgf_s[] = { + { CKG_MGF1_SHA1 , "CKG_MGF1_SHA1 " }, + { CKG_MGF1_SHA224, "CKG_MGF1_SHA224" }, + { CKG_MGF1_SHA256, "CKG_MGF1_SHA256" }, + { CKG_MGF1_SHA384, "CKG_MGF1_SHA384" }, + { CKG_MGF1_SHA512, "CKG_MGF1_SHA512" }, +}; + static enum_specs ck_err_s[] = { { CKR_OK, "CKR_OK" }, { CKR_CANCEL, "CKR_CANCEL" }, @@ -630,6 +638,7 @@ enum_spec ck_types[] = { { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" }, { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" }, { MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" }, + { MGF_T, ck_mgf_s, sizeof(ck_mgf_s) / SZ_SPECS, "CK_RSA_PKCS_MGF_TYPE"}, { USR_T, ck_usr_s, sizeof(ck_usr_s) / SZ_SPECS, "CK_USER_TYPE" }, { STA_T, ck_sta_s, sizeof(ck_sta_s) / SZ_SPECS, "CK_STATE" }, { RV_T, ck_err_s, sizeof(ck_err_s) / SZ_SPECS, "CK_RV" }, diff --git a/src/pkcs11/pkcs11-display.h b/src/pkcs11/pkcs11-display.h index 0f7bc5fb38..9473ce9c08 100644 --- a/src/pkcs11/pkcs11-display.h +++ b/src/pkcs11/pkcs11-display.h @@ -56,6 +56,7 @@ enum ck_type{ KEY_T, CRT_T, MEC_T, + MGF_T, USR_T, STA_T, RV_T diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index d0201772ed..7a828a1a33 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -969,6 +969,15 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA enter("C_SignInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); + if (pMechanism->pParameter != NULL) { /* XXX assuming PSS parameter */ + CK_RSA_PKCS_PSS_PARAMS *param = + (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", param->sLen); + } spy_dump_ulong_in("hKey", hKey); rv = po->C_SignInit(hSession, pMechanism, hKey); return retne(rv); From 1efb7749a64ac596fc03c6a6bcdddddf73db1d63 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 6 Sep 2017 16:13:18 +0200 Subject: [PATCH 05/20] Enable RSA-PSS signatures in pkcs11-tool --- doc/tools/pkcs11-tool.1.xml | 25 ++++++++ src/tools/pkcs11-tool.c | 118 ++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 45a0683fc4..660a271f79 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -71,6 +71,13 @@ Hash some data. + + + mechanism + + Specify hash algorithm used with generic RSA-PSS signature + + id, @@ -212,6 +219,16 @@ of mechanisms supported by your token. + + + function + + Use the specified Message Generation + Function (MGF) function + for RSA-PSS signatures. Supported arguments are MGF1-SHA1 + to MGF1-SHA512 if supported by the driver. + + mod @@ -309,6 +326,14 @@ Derive a secret key using another key and some data. + + + bytes + + Specify how many bytes should be used in + RSA-PSS signatures. Default is 0. + + id diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 4240a0c30b..7cc9d2b378 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -146,6 +146,9 @@ enum { OPT_TEST_FORK, OPT_GENERATE_KEY, OPT_GENERATE_RANDOM, + OPT_HASH_ALGORITHM, + OPT_MGF, + OPT_SALT, }; static const struct option options[] = { @@ -162,6 +165,9 @@ static const struct option options[] = { { "derive", 0, NULL, OPT_DERIVE }, { "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER }, { "mechanism", 1, NULL, 'm' }, + { "hash-algorithm", 1, NULL, OPT_HASH_ALGORITHM }, + { "mgf", 1, NULL, OPT_MGF }, + { "salt", 1, NULL, OPT_SALT }, { "login", 0, NULL, 'l' }, { "login-type", 1, NULL, OPT_LOGIN_TYPE }, @@ -227,6 +233,9 @@ static const char *option_help[] = { "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", "Specify mechanism (use -M for a list of supported mechanisms)", + "Specify hash algorithm used with generic RSA-PSS signature", + "Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)", + "Specify how many bytes should be used for salt in RSA-PSS signatures (default 0)", "Log into the token first", "Specify login type ('so', 'user', 'context-specific'; default:'user')", @@ -316,6 +325,9 @@ static int opt_key_usage_derive = 0; static int opt_key_usage_default = 1; /* uses defaults if no opt_key_usage options */ static int opt_derive_pass_der = 0; static unsigned long opt_random_bytes = 0; +static CK_MECHANISM_TYPE opt_hash_alg = 0; +static unsigned long opt_mgf = 0; +static unsigned long opt_salt = 0; static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -406,6 +418,8 @@ static const char * p11_utf8_to_local(CK_UTF8CHAR *, size_t); static const char * p11_flag_names(struct flag_info *, CK_FLAGS); static const char * p11_mechanism_to_name(CK_MECHANISM_TYPE); static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *); +static const char * p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE); +static CK_MECHANISM_TYPE p11_name_to_mgf(const char *); static void p11_perror(const char *, CK_RV); static const char * CKR2Str(CK_ULONG res); static int p11_test(CK_SESSION_HANDLE session); @@ -673,6 +687,15 @@ int main(int argc, char * argv[]) opt_mechanism_used = 1; opt_mechanism = p11_name_to_mechanism(optarg); break; + case OPT_HASH_ALGORITHM: + opt_hash_alg = p11_name_to_mechanism(optarg); + break; + case OPT_MGF: + opt_mgf = p11_name_to_mgf(optarg); + break; + case OPT_SALT: + opt_salt = (CK_ULONG) strtoul(optarg, NULL, 0); + break; case 'o': opt_output = optarg; break; @@ -1607,6 +1630,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, { unsigned char in_buffer[1025], sig_buffer[512]; CK_MECHANISM mech; + CK_RSA_PKCS_PSS_PARAMS pss_params; CK_RV rv; CK_ULONG sig_len; int fd, r; @@ -1618,6 +1642,67 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, fprintf(stderr, "Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; + pss_params.hashAlg = 0; + + if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS) + util_fatal("The hash-algorithm is applicable only to generic" + "RSA-PKCS-PSS mechanism"); + + /* set "default" MGF and hash algorithms. We can overwrite MGF later */ + switch (opt_mechanism) { + case CKM_RSA_PKCS_PSS: + switch (opt_hash_alg) { + case CKM_SHA_1: + pss_params.mgf = CKG_MGF1_SHA1; + break; + case CKM_SHA256: + pss_params.mgf = CKG_MGF1_SHA256; + break; + case CKM_SHA384: + pss_params.mgf = CKG_MGF1_SHA384; + break; + case CKM_SHA512: + pss_params.mgf = CKG_MGF1_SHA512; + break; + default: + util_fatal("RSA-PKCS-PSS requires explicit hash mechanism"); + } + pss_params.hashAlg = opt_hash_alg; + break; + + case CKM_SHA1_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA_1; + pss_params.mgf = CKG_MGF1_SHA1; + break; + + case CKM_SHA256_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA256; + pss_params.mgf = CKG_MGF1_SHA256; + break; + + case CKM_SHA384_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA384; + pss_params.mgf = CKG_MGF1_SHA384; + break; + + case CKM_SHA512_RSA_PKCS_PSS: + pss_params.hashAlg = CKM_SHA512; + pss_params.mgf = CKG_MGF1_SHA512; + break; + } + + /* One of RSA-PSS mechanisms above: They need parameters */ + if (pss_params.hashAlg) { + if (opt_mgf != 0) + pss_params.mgf = opt_mgf; + pss_params.sLen = opt_salt; + mech.pParameter = &pss_params; + mech.ulParameterLen = sizeof(pss_params); + fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", + p11_mechanism_to_name(opt_mechanism), + p11_mgf_to_name(pss_params.mgf), + pss_params.sLen); + } if (opt_input == NULL) fd = 0; @@ -5812,6 +5897,15 @@ static struct mech_info p11_mechanisms[] = { { 0, NULL, NULL } }; +static struct mech_info p11_mgf[] = { + { CKG_MGF1_SHA1, "MGF1-SHA1", NULL }, + { CKG_MGF1_SHA224, "MGF1-SHA224", NULL }, + { CKG_MGF1_SHA256, "MGF1-SHA256", NULL }, + { CKG_MGF1_SHA384, "MGF1-SHA384", NULL }, + { CKG_MGF1_SHA512, "MGF1-SHA512", NULL }, + { 0, NULL, NULL } +}; + static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech) { static char temp[64]; @@ -5838,6 +5932,30 @@ static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *name) return 0; /* gcc food */ } +static CK_RSA_PKCS_MGF_TYPE p11_name_to_mgf(const char *name) +{ + struct mech_info *mi; + + for (mi = p11_mgf; mi->name; mi++) { + if (!strcasecmp(mi->name, name)) + return mi->mech; + } + util_fatal("Unknown PKCS11 MGF \"%s\"", name); +} + +static const char *p11_mgf_to_name(CK_RSA_PKCS_MGF_TYPE mgf) +{ + static char temp[64]; + struct mech_info *mi; + + for (mi = p11_mgf; mi->name; mi++) { + if (mi->mech == mgf) + return mi->name; + } + snprintf(temp, sizeof(temp), "mgf-0x%lX", (unsigned long) mgf); + return temp; +} + static const char * CKR2Str(CK_ULONG res) { switch (res) { From c2d8ee508cbfa2c850015a3d73348def3e6baf63 Mon Sep 17 00:00:00 2001 From: Uri Blumenthal Date: Thu, 7 Sep 2017 12:07:51 -0400 Subject: [PATCH 06/20] Added short names to RSA-PSS methods --- src/tools/pkcs11-tool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7cc9d2b378..0649a939b6 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -5717,10 +5717,10 @@ static struct mech_info p11_mechanisms[] = { { CKM_RSA_X9_31, "RSA-X9-31", NULL }, { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL }, { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL }, - { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", NULL }, - { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", NULL }, - { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", NULL }, - { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", NULL }, + { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", "rsa-pss-sha1" }, + { CKM_SHA256_RSA_PKCS_PSS,"SHA256-RSA-PKCS-PSS", "rsa-pss-sha256" }, + { CKM_SHA384_RSA_PKCS_PSS,"SHA384-RSA-PKCS-PSS", "rsa-pss-sha384" }, + { CKM_SHA512_RSA_PKCS_PSS,"SHA512-RSA-PKCS-PSS", "rsa-pss-sha512" }, { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL }, { CKM_DSA, "DSA", NULL }, { CKM_DSA_SHA1, "DSA-SHA1", NULL }, From ec8dd42d8c613d30d10bf8131b16a4e644eb7155 Mon Sep 17 00:00:00 2001 From: Uri Blumenthal Date: Thu, 7 Sep 2017 15:10:52 -0400 Subject: [PATCH 07/20] Change RSA-PSS salt length default to OpenSSL-compatible, aka digest size --- src/tools/pkcs11-tool.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0649a939b6..1e411e6f95 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -235,7 +235,7 @@ static const char *option_help[] = { "Specify mechanism (use -M for a list of supported mechanisms)", "Specify hash algorithm used with generic RSA-PSS signature", "Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)", - "Specify how many bytes should be used for salt in RSA-PSS signatures (default 0)", + "Specify how many bytes should be used for salt in RSA-PSS signatures (default equals to digest size)", "Log into the token first", "Specify login type ('so', 'user', 'context-specific'; default:'user')", @@ -328,6 +328,7 @@ static unsigned long opt_random_bytes = 0; static CK_MECHANISM_TYPE opt_hash_alg = 0; static unsigned long opt_mgf = 0; static unsigned long opt_salt = 0; +static int opt_salt_given = 0; /* 0 - not given, 1 - given with input parameters */ static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -695,6 +696,7 @@ int main(int argc, char * argv[]) break; case OPT_SALT: opt_salt = (CK_ULONG) strtoul(optarg, NULL, 0); + opt_salt_given = 1; break; case 'o': opt_output = optarg; @@ -1625,6 +1627,28 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } +inline unsigned long figure_pss_salt_length(const int hash) { + unsigned sLen = 0; + switch (hash) { + case CKM_SHA_1: + sLen = 20; + break; + case CKM_SHA256: + sLen = 32; + break; + case CKM_SHA384: + sLen = 48; + break; + case CKM_SHA512: + sLen = 64; + break; + default: + sLen = 0; + break; + } + return sLen; +} + static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { @@ -1666,7 +1690,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; default: util_fatal("RSA-PKCS-PSS requires explicit hash mechanism"); - } + } pss_params.hashAlg = opt_hash_alg; break; @@ -1695,7 +1719,10 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (pss_params.hashAlg) { if (opt_mgf != 0) pss_params.mgf = opt_mgf; - pss_params.sLen = opt_salt; + if (opt_salt_given == 1) + pss_params.sLen = opt_salt; + else + pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", From aaecfdb5c48d917f2c52cfabbccedad3123c0ade Mon Sep 17 00:00:00 2001 From: Uri Blumenthal Date: Thu, 7 Sep 2017 16:20:01 -0400 Subject: [PATCH 08/20] Fixed hashAlg but in pkcs11-tool for RSA-PSS --- src/tools/pkcs11-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 1e411e6f95..b2a9473f98 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1726,9 +1726,9 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", - p11_mechanism_to_name(opt_mechanism), - p11_mgf_to_name(pss_params.mgf), - pss_params.sLen); + p11_mechanism_to_name(pss_params.hashAlg), + p11_mgf_to_name(pss_params.mgf), + pss_params.sLen); } if (opt_input == NULL) From da9bae038cbe757ef4c775086335fb7c7c6d4287 Mon Sep 17 00:00:00 2001 From: Mouse Date: Fri, 8 Sep 2017 07:23:57 -0400 Subject: [PATCH 09/20] CHanged opt_salt to salt_len --- src/tools/pkcs11-tool.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b2a9473f98..029ab23982 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -327,8 +327,8 @@ static int opt_derive_pass_der = 0; static unsigned long opt_random_bytes = 0; static CK_MECHANISM_TYPE opt_hash_alg = 0; static unsigned long opt_mgf = 0; -static unsigned long opt_salt = 0; -static int opt_salt_given = 0; /* 0 - not given, 1 - given with input parameters */ +static long salt_len = 0; +static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -695,8 +695,8 @@ int main(int argc, char * argv[]) opt_mgf = p11_name_to_mgf(optarg); break; case OPT_SALT: - opt_salt = (CK_ULONG) strtoul(optarg, NULL, 0); - opt_salt_given = 1; + salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); + salt_len_given = 1; break; case 'o': opt_output = optarg; @@ -1719,8 +1719,8 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (pss_params.hashAlg) { if (opt_mgf != 0) pss_params.mgf = opt_mgf; - if (opt_salt_given == 1) - pss_params.sLen = opt_salt; + if (salt_len_given == 1) + pss_params.sLen = salt_len; else pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); mech.pParameter = &pss_params; From 7513ec26e2bc0187b5c1a90543ce1b02880d1b0c Mon Sep 17 00:00:00 2001 From: Mouse Date: Fri, 8 Sep 2017 20:56:59 -0400 Subject: [PATCH 10/20] Fixed type of salt length from unsigned long to long --- src/tools/pkcs11-tool.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 029ab23982..2f400010a1 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1627,7 +1627,7 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } -inline unsigned long figure_pss_salt_length(const int hash) { +inline long figure_pss_salt_length(const int hash) { unsigned sLen = 0; switch (hash) { case CKM_SHA_1: @@ -1719,16 +1719,16 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (pss_params.hashAlg) { if (opt_mgf != 0) pss_params.mgf = opt_mgf; - if (salt_len_given == 1) - pss_params.sLen = salt_len; - else - pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); + if (salt_len_given == 1) + pss_params.sLen = salt_len; + else + pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", - p11_mechanism_to_name(pss_params.hashAlg), - p11_mgf_to_name(pss_params.mgf), - pss_params.sLen); + p11_mechanism_to_name(pss_params.hashAlg), + p11_mgf_to_name(pss_params.mgf), + pss_params.sLen); } if (opt_input == NULL) From cedbd3eef11840a5f0dfee29d18a69531eb3c72f Mon Sep 17 00:00:00 2001 From: Mouse Date: Fri, 8 Sep 2017 21:51:45 -0400 Subject: [PATCH 11/20] RSA-PSS: made sure special values for salt length from OpenSSL ("-1" and "-2") are processed correctly, and compatible with OpenSSL --- doc/tools/pkcs11-tool.1.xml | 2 +- src/tools/pkcs11-tool.c | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index 660a271f79..fa8113705c 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -331,7 +331,7 @@ bytes Specify how many bytes should be used in - RSA-PSS signatures. Default is 0. + RSA-PSS signatures. Can be zero (no salt). Accepts two special values: "-1" means salt length equals to digest length, "-2" means use maximum permissible length. Default is digest length. diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2f400010a1..9ecc3636d1 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1627,7 +1627,7 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } -inline long figure_pss_salt_length(const int hash) { +static unsigned long figure_pss_salt_length(const int hash) { unsigned sLen = 0; switch (hash) { case CKM_SHA_1: @@ -1719,10 +1719,17 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (pss_params.hashAlg) { if (opt_mgf != 0) pss_params.mgf = opt_mgf; - if (salt_len_given == 1) - pss_params.sLen = salt_len; - else - pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); + if ((salt_len_given == 1) && (salt_len != -1) && (salt_len != -2)) { + pss_params.sLen = salt_len; /* use given size in bytes */ + } else { + if (salt_len == -2) { /* maximum permissible salt len */ + unsigned long modlen = (get_private_key_length(session, key) + 7) / 8; + unsigned long saltlen = figure_pss_salt_length(pss_params.hashAlg); + pss_params.sLen = modlen - saltlen -2; + } else { /* size of digest */ + pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); + } + } mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", From 0b7e5f0f54087ce23c20e77f8df66c99f6a4c1c7 Mon Sep 17 00:00:00 2001 From: Mouse Date: Sat, 9 Sep 2017 20:06:45 -0400 Subject: [PATCH 12/20] Refactored dealing with salt length, and added input check --- src/tools/pkcs11-tool.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9ecc3636d1..99753a0652 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1627,8 +1627,9 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) return 0; } +/* return digest length in bytes */ static unsigned long figure_pss_salt_length(const int hash) { - unsigned sLen = 0; + unsigned long sLen = 0; switch (hash) { case CKM_SHA_1: sLen = 20; @@ -1719,17 +1720,31 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (pss_params.hashAlg) { if (opt_mgf != 0) pss_params.mgf = opt_mgf; - if ((salt_len_given == 1) && (salt_len != -1) && (salt_len != -2)) { - pss_params.sLen = salt_len; /* use given size in bytes */ - } else { - if (salt_len == -2) { /* maximum permissible salt len */ - unsigned long modlen = (get_private_key_length(session, key) + 7) / 8; - unsigned long saltlen = figure_pss_salt_length(pss_params.hashAlg); - pss_params.sLen = modlen - saltlen -2; - } else { /* size of digest */ - pss_params.sLen = figure_pss_salt_length(pss_params.hashAlg); - } + + + unsigned long hashlen = figure_pss_salt_length(pss_params.hashAlg); + if (salt_len_given == 1) { /* salt size explicitly given */ + if (salt_len < 0 && salt_len != -1 && salt_len != -2) + util_fatal("Salt length must be greater or equal \ +to zero, or equal to -1 (meaning: use digest size) or to -2 \ +(meaning: use maximum permissible size"); + + unsigned long modlen = (get_private_key_length(session, key) + 7) / 8; + switch(salt_len) { + case -1: /* salt size equals to digest size */ + pss_params.sLen = hashlen; + break; + case -2: /* maximum permissible salt len */ + pss_params.sLen = modlen - hashlen -2; + break; + default: /* use given size but its value must be >= 0 */ + pss_params.sLen = salt_len; + break; + } /* end switch (salt_len_given) */ + } else { /* use default: salt len of digest size */ + pss_params.sLen = hashlen; } + mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", From f2f53c1fad2b8e4f8290a235877d863fd14d3281 Mon Sep 17 00:00:00 2001 From: Mouse Date: Sun, 10 Sep 2017 20:27:51 -0400 Subject: [PATCH 13/20] Fix introduced incompatibility with C90 standard (declaration of variables inside the code) --- src/tools/pkcs11-tool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 99753a0652..da8b8472b7 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1660,6 +1660,8 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_ULONG sig_len; int fd, r; + unsigned long hashlen = 0, modlen = 0; + if (!opt_mechanism_used) if (!find_mechanism(slot, CKF_SIGN|CKF_HW, NULL, 0, &opt_mechanism)) util_fatal("Sign mechanism not supported"); @@ -1721,15 +1723,15 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, if (opt_mgf != 0) pss_params.mgf = opt_mgf; + hashlen = figure_pss_salt_length(pss_params.hashAlg); - unsigned long hashlen = figure_pss_salt_length(pss_params.hashAlg); if (salt_len_given == 1) { /* salt size explicitly given */ if (salt_len < 0 && salt_len != -1 && salt_len != -2) util_fatal("Salt length must be greater or equal \ to zero, or equal to -1 (meaning: use digest size) or to -2 \ (meaning: use maximum permissible size"); - unsigned long modlen = (get_private_key_length(session, key) + 7) / 8; + modlen = (get_private_key_length(session, key) + 7) / 8; switch(salt_len) { case -1: /* salt size equals to digest size */ pss_params.sLen = hashlen; From ebd3ca2354d5b3c5624b9748a28dd21ee07cbf0e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Sep 2017 12:46:34 +0200 Subject: [PATCH 14/20] Whitespace cleanup of mouse07410 commits --- src/tools/pkcs11-tool.c | 80 ++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index da8b8472b7..7504b055b2 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -328,7 +328,7 @@ static unsigned long opt_random_bytes = 0; static CK_MECHANISM_TYPE opt_hash_alg = 0; static unsigned long opt_mgf = 0; static long salt_len = 0; -static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ +static int salt_len_given = 0; /* 0 - not given, 1 - given with input parameters */ static void *module = NULL; static CK_FUNCTION_LIST_PTR p11 = NULL; @@ -696,7 +696,7 @@ int main(int argc, char * argv[]) break; case OPT_SALT: salt_len = (CK_ULONG) strtoul(optarg, NULL, 0); - salt_len_given = 1; + salt_len_given = 1; break; case 'o': opt_output = optarg; @@ -1629,25 +1629,25 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) /* return digest length in bytes */ static unsigned long figure_pss_salt_length(const int hash) { - unsigned long sLen = 0; - switch (hash) { - case CKM_SHA_1: - sLen = 20; - break; - case CKM_SHA256: - sLen = 32; - break; - case CKM_SHA384: - sLen = 48; - break; - case CKM_SHA512: - sLen = 64; - break; - default: - sLen = 0; - break; - } - return sLen; + unsigned long sLen = 0; + switch (hash) { + case CKM_SHA_1: + sLen = 20; + break; + case CKM_SHA256: + sLen = 32; + break; + case CKM_SHA384: + sLen = 48; + break; + case CKM_SHA512: + sLen = 64; + break; + default: + sLen = 0; + break; + } + return sLen; } static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, @@ -1693,7 +1693,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, break; default: util_fatal("RSA-PKCS-PSS requires explicit hash mechanism"); - } + } pss_params.hashAlg = opt_hash_alg; break; @@ -1726,33 +1726,33 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, hashlen = figure_pss_salt_length(pss_params.hashAlg); if (salt_len_given == 1) { /* salt size explicitly given */ - if (salt_len < 0 && salt_len != -1 && salt_len != -2) - util_fatal("Salt length must be greater or equal \ + if (salt_len < 0 && salt_len != -1 && salt_len != -2) + util_fatal("Salt length must be greater or equal \ to zero, or equal to -1 (meaning: use digest size) or to -2 \ (meaning: use maximum permissible size"); - modlen = (get_private_key_length(session, key) + 7) / 8; - switch(salt_len) { - case -1: /* salt size equals to digest size */ - pss_params.sLen = hashlen; - break; - case -2: /* maximum permissible salt len */ - pss_params.sLen = modlen - hashlen -2; - break; - default: /* use given size but its value must be >= 0 */ - pss_params.sLen = salt_len; - break; - } /* end switch (salt_len_given) */ + modlen = (get_private_key_length(session, key) + 7) / 8; + switch(salt_len) { + case -1: /* salt size equals to digest size */ + pss_params.sLen = hashlen; + break; + case -2: /* maximum permissible salt len */ + pss_params.sLen = modlen - hashlen -2; + break; + default: /* use given size but its value must be >= 0 */ + pss_params.sLen = salt_len; + break; + } /* end switch (salt_len_given) */ } else { /* use default: salt len of digest size */ - pss_params.sLen = hashlen; + pss_params.sLen = hashlen; } mech.pParameter = &pss_params; mech.ulParameterLen = sizeof(pss_params); fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n", - p11_mechanism_to_name(pss_params.hashAlg), - p11_mgf_to_name(pss_params.mgf), - pss_params.sLen); + p11_mechanism_to_name(pss_params.hashAlg), + p11_mgf_to_name(pss_params.mgf), + pss_params.sLen); } if (opt_input == NULL) From 55f06162cd6e588ef9655946a5d8ca26b6b08cc5 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Sep 2017 17:19:15 +0200 Subject: [PATCH 15/20] Add SHA-224 hash algorithm for RSA-PSS --- src/tools/pkcs11-tool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 7504b055b2..027a405355 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1634,6 +1634,9 @@ static unsigned long figure_pss_salt_length(const int hash) { case CKM_SHA_1: sLen = 20; break; + case CKM_SHA224: + sLen = 28; + break; case CKM_SHA256: sLen = 32; break; From 15659fbbc2428d0ee3216c665790ff251c376081 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Sep 2017 17:19:46 +0200 Subject: [PATCH 16/20] Do not fallback to zero-length salt on unknown hash algorithms --- src/tools/pkcs11-tool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 027a405355..8b00f14cac 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1647,7 +1647,8 @@ static unsigned long figure_pss_salt_length(const int hash) { sLen = 64; break; default: - sLen = 0; + util_fatal("Unknown hash algorithm '%s' for RSA-PSS signatures", + p11_mechanism_to_name(hash)); break; } return sLen; From 375e1c22ef26e959c8d812d97465ce4511477191 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 11 Sep 2017 18:17:58 +0200 Subject: [PATCH 17/20] Add SHA224 definitions in pkcs11.h (for completenes) --- src/pkcs11/pkcs11.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index ac8ae7212b..d24597b26f 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -559,6 +559,9 @@ typedef unsigned long int ck_rsa_pkcs_mgf_type_t; #define CKM_SHA256 (0x250UL) #define CKM_SHA256_HMAC (0x251UL) #define CKM_SHA256_HMAC_GENERAL (0x252UL) +#define CKM_SHA224 (0x255UL) +#define CKM_SHA224_HMAC (0x256UL) +#define CKM_SHA224_HMAC_GENERAL (0x257UL) #define CKM_SHA384 (0x260UL) #define CKM_SHA384_HMAC (0x261UL) #define CKM_SHA384_HMAC_GENERAL (0x262UL) From 4450c2c0e5d928a38e602b8bce5f446cdf9eee92 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 13 Sep 2017 11:02:00 +0200 Subject: [PATCH 18/20] Reintroduce portable NORETURN indication for functions and use it to avoid compilers complaining --- src/tools/util.c | 5 +++-- src/tools/util.h | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/tools/util.c b/src/tools/util.c index f5a0370090..9c9f37c8bf 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -232,7 +232,8 @@ void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr) } } -void util_print_usage_and_die(const char *app_name, const struct option options[], +NORETURN void +util_print_usage_and_die(const char *app_name, const struct option options[], const char *option_help[], const char *args) { int i; @@ -343,7 +344,7 @@ const char * util_acl_to_str(const sc_acl_entry_t *e) return line; } -void +NORETURN void util_fatal(const char *fmt, ...) { va_list ap; diff --git a/src/tools/util.h b/src/tools/util.h index b907808773..d3a155708f 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -23,15 +23,28 @@ extern "C" { #endif +#if _MSC_VER >= 1310 +/* MS Visual Studio 2003/.NET Framework 1.1 or newer */ +# define NORETURN _declspec( noreturn) +#elif __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ >= 5)) || (defined __clang__) +# define NORETURN __attribute__ ((noreturn)) +#elif __cplusplus >= 201103L +# define NORETURN [[noreturn]] +#elif __STDC_VERSION__ >= 201112L +# define NORETURN _Noreturn +#else +# define NORETURN +#endif + void util_print_binary(FILE *f, const u8 *buf, int count); void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep); void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr); -void util_print_usage_and_die(const char *app_name, const struct option options[], +NORETURN void util_print_usage_and_die(const char *app_name, const struct option options[], const char *option_help[], const char *args); const char * util_acl_to_str(const struct sc_acl_entry *e); void util_warn(const char *fmt, ...); void util_error(const char *fmt, ...); -void util_fatal(const char *fmt, ...); +NORETURN void util_fatal(const char *fmt, ...); /* All singing all dancing card connect routine */ int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock, int verbose); int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int verbose); From e87070646f20ae2d17cfd6b63759a5b0ecd9729e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 15 Sep 2017 18:44:20 +0200 Subject: [PATCH 19/20] Use default SHA-1 mechanisms, use --salt-len, improve wording of documentation --- doc/tools/pkcs11-tool.1.xml | 15 ++++++++++----- src/tools/pkcs11-tool.c | 20 +++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml index fa8113705c..037c955146 100644 --- a/doc/tools/pkcs11-tool.1.xml +++ b/doc/tools/pkcs11-tool.1.xml @@ -75,7 +75,8 @@ mechanism - Specify hash algorithm used with generic RSA-PSS signature + Specify hash algorithm used with + RSA-PKCS-PSS signature. Default is SHA-1. @@ -226,7 +227,8 @@ Use the specified Message Generation Function (MGF) function for RSA-PSS signatures. Supported arguments are MGF1-SHA1 - to MGF1-SHA512 if supported by the driver. + to MGF1-SHA512 if supported by the driver. + The default is based on the hash selection. @@ -328,10 +330,13 @@ - bytes + bytes - Specify how many bytes should be used in - RSA-PSS signatures. Can be zero (no salt). Accepts two special values: "-1" means salt length equals to digest length, "-2" means use maximum permissible length. Default is digest length. + Specify how many bytes of salt should + be used in RSA-PSS signatures. Accepts two special values: + "-1" means salt length equals to digest length, + "-2" means use maximum permissible length. + Default is digest length (-1). diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 8b00f14cac..744b6cfada 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -167,7 +167,7 @@ static const struct option options[] = { { "mechanism", 1, NULL, 'm' }, { "hash-algorithm", 1, NULL, OPT_HASH_ALGORITHM }, { "mgf", 1, NULL, OPT_MGF }, - { "salt", 1, NULL, OPT_SALT }, + { "salt-len", 1, NULL, OPT_SALT }, { "login", 0, NULL, 'l' }, { "login-type", 1, NULL, OPT_LOGIN_TYPE }, @@ -233,9 +233,9 @@ static const char *option_help[] = { "Derive a secret key using another key and some data", "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations", "Specify mechanism (use -M for a list of supported mechanisms)", - "Specify hash algorithm used with generic RSA-PSS signature", + "Specify hash algorithm used with RSA-PKCS-PSS signature", "Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)", - "Specify how many bytes should be used for salt in RSA-PSS signatures (default equals to digest size)", + "Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)", "Log into the token first", "Specify login type ('so', 'user', 'context-specific'; default:'user')", @@ -1676,16 +1676,15 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, pss_params.hashAlg = 0; if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_PSS) - util_fatal("The hash-algorithm is applicable only to generic" + util_fatal("The hash-algorithm is applicable only to " "RSA-PKCS-PSS mechanism"); /* set "default" MGF and hash algorithms. We can overwrite MGF later */ switch (opt_mechanism) { case CKM_RSA_PKCS_PSS: + pss_params.hashAlg = opt_hash_alg; + switch (opt_hash_alg) { - case CKM_SHA_1: - pss_params.mgf = CKG_MGF1_SHA1; - break; case CKM_SHA256: pss_params.mgf = CKG_MGF1_SHA256; break; @@ -1696,9 +1695,12 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, pss_params.mgf = CKG_MGF1_SHA512; break; default: - util_fatal("RSA-PKCS-PSS requires explicit hash mechanism"); + /* the PSS should use SHA-1 if not specified */ + pss_params.hashAlg = CKM_SHA_1; + /* fallthrough */ + case CKM_SHA_1: + pss_params.mgf = CKG_MGF1_SHA1; } - pss_params.hashAlg = opt_hash_alg; break; case CKM_SHA1_RSA_PKCS_PSS: From 63ae2f90cc3bf0fa879e1ec03c636658de5b9d34 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 18 Sep 2017 10:46:23 +0200 Subject: [PATCH 20/20] Check the mechanism type before dereferencing generic parameter --- src/pkcs11/pkcs11-spy.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/pkcs11/pkcs11-spy.c b/src/pkcs11/pkcs11-spy.c index 7a828a1a33..8011f0471c 100644 --- a/src/pkcs11/pkcs11-spy.c +++ b/src/pkcs11/pkcs11-spy.c @@ -969,14 +969,23 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA enter("C_SignInit"); spy_dump_ulong_in("hSession", hSession); fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism)); - if (pMechanism->pParameter != NULL) { /* XXX assuming PSS parameter */ - CK_RSA_PKCS_PSS_PARAMS *param = - (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; - fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", - lookup_enum(MEC_T, param->hashAlg)); - fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", - lookup_enum(MGF_T, param->mgf)); - fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", param->sLen); + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + if (pMechanism->pParameter != NULL) { + CK_RSA_PKCS_PSS_PARAMS *param = + (CK_RSA_PKCS_PSS_PARAMS *) pMechanism->pParameter; + fprintf(spy_output, "pMechanism->pParameter->hashAlg=%s\n", + lookup_enum(MEC_T, param->hashAlg)); + fprintf(spy_output, "pMechanism->pParameter->mgf=%s\n", + lookup_enum(MGF_T, param->mgf)); + fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n", + param->sLen); + } + break; } spy_dump_ulong_in("hKey", hKey); rv = po->C_SignInit(hSession, pMechanism, hKey);