From 0e12b1dc711c6296155c336b904516de2443c589 Mon Sep 17 00:00:00 2001 From: Dmitriy Fortinskiy Date: Thu, 21 Mar 2019 15:29:32 +0300 Subject: [PATCH] pkcs11-tool: Generate GOSTR3410-2012 keys --- src/pkcs11/pkcs11.h | 15 ++++++ src/tools/pkcs11-tool.c | 114 +++++++++++++++++++++++++++++----------- 2 files changed, 99 insertions(+), 30 deletions(-) diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index 2384f91e..e24734c6 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -361,6 +361,12 @@ typedef unsigned long ck_key_type_t; #define CKK_GOST28147 (0x32UL) #define CKK_VENDOR_DEFINED (1UL << 31) +// A mask for new GOST algorithms. +// For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html +#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) +#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM + +#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003) typedef unsigned long ck_certificate_type_t; @@ -709,8 +715,17 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) #define CKM_GOSTR3410_KEY_WRAP (0x1203UL) #define CKM_GOSTR3410_DERIVE (0x1204UL) +#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005) +#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006) +#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009) #define CKM_GOSTR3411 (0x1210UL) #define CKM_GOSTR3411_HMAC (0x1211UL) +#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012) +#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013) +#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014) +#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015) #define CKM_GOST28147_KEY_GEN (0x1220UL) #define CKM_GOST28147_ECB (0x1221UL) #define CKM_GOST28147 (0x1222UL) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index b0401005..24ab6137 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -264,7 +264,7 @@ static const char *option_help[] = { "Unlock User PIN (without '--login' unlock in logged in session; otherwise '--login-type' has to be 'context-specific')", "Key pair generation", "Key generation", - "Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1 or GOSTR3410:A", + "Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1 or GOSTR3410-2012-256:B", "Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey)", "Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey)", "Specify 'derive' key usage flag (EC only)", @@ -2336,49 +2336,103 @@ static int gen_keypair(CK_SLOT_ID slot, CK_SESSION_HANDLE session, FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_EC_PARAMS, ecparams, ecparams_size); n_pubkey_attr++; } - else if (strncmp(type, "GOSTR3410:", strlen("GOSTR3410:")) == 0 || strncmp(type, "gostr3410:", strlen("gostr3410:")) == 0) { - CK_BYTE key_paramset_encoded_oid[9]; - CK_BYTE hash_paramset_encoded_oid[9]; - const CK_BYTE GOST_PARAMSET_A_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01}; - const CK_BYTE GOST_PARAMSET_B_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02}; - const CK_BYTE GOST_PARAMSET_C_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03}; - const CK_BYTE GOST_HASH_PARAMSET_OID[] = {0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01}; - unsigned long int gost_key_type = CKK_GOSTR3410; - CK_MECHANISM_TYPE mtypes[] = {CKM_GOSTR3410_KEY_PAIR_GEN}; + else if (strncmp(type, "GOSTR3410", strlen("GOSTR3410")) == 0 || strncmp(type, "gostr3410", strlen("gostr3410")) == 0) { + const struct sc_aid GOST2001_PARAMSET_A_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 }, 9 }; + const struct sc_aid GOST2001_PARAMSET_B_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02 }, 9 }; + const struct sc_aid GOST2001_PARAMSET_C_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 }, 9 }; + const struct sc_aid GOST2012_256_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x01, 0x01 }, 11 }; + const struct sc_aid GOST2012_512_PARAMSET_A_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01 }, 11 }; + const struct sc_aid GOST2012_512_PARAMSET_B_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x02 }, 11 }; + const struct sc_aid GOST2012_512_PARAMSET_C_OID = { { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x03 }, 11 }; + const struct sc_aid GOST_HASH2001_PARAMSET_OID = { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }, 9 }; + const struct sc_aid GOST_HASH2012_256_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 }, 10 }; + const struct sc_aid GOST_HASH2012_512_PARAMSET_OID = { { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 }, 10 }; + struct sc_aid key_paramset_encoded_oid; + struct sc_aid hash_paramset_encoded_oid; + unsigned long int gost_key_type = -1; + CK_MECHANISM_TYPE mtypes[] = {-1}; size_t mtypes_num = sizeof(mtypes)/sizeof(mtypes[0]); - const char *p_param_set = type + strlen("GOSTR3410:"); - - if (!opt_mechanism_used) { - if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) - util_fatal("Generate GOSTR3410 mechanism not supported"); - } + const char *p_param_set = type + strlen("GOSTR3410"); if (p_param_set == NULL) util_fatal("Unknown key type %s", type); - if (!strcmp("A", p_param_set)) { - memcpy(key_paramset_encoded_oid, GOST_PARAMSET_A_OID, sizeof(GOST_PARAMSET_A_OID)); - memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID)); + if (!strcmp(":A", p_param_set) || !strcmp("-2001:A", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID; } - else if (!strcmp("B", p_param_set)) { - memcpy(key_paramset_encoded_oid, GOST_PARAMSET_B_OID, sizeof(GOST_PARAMSET_B_OID)); - memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID)); + else if (!strcmp(":B", p_param_set) || !strcmp("-2001:B", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_B_OID; + hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID; } - else if (!strcmp("C", p_param_set)) { - memcpy(key_paramset_encoded_oid, GOST_PARAMSET_C_OID, sizeof(GOST_PARAMSET_C_OID)); - memcpy(hash_paramset_encoded_oid, GOST_HASH_PARAMSET_OID, sizeof(GOST_HASH_PARAMSET_OID)); + else if (!strcmp(":C", p_param_set) || !strcmp("-2001:C", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_C_OID; + hash_paramset_encoded_oid = GOST_HASH2001_PARAMSET_OID; + } else if (!strcmp("-2012-256:A", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_256_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; + } + else if (!strcmp("-2012-256:B", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; + } + else if (!strcmp("-2012-256:C", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_B_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; + } + else if (!strcmp("-2012-256:D", p_param_set)) { + gost_key_type = CKK_GOSTR3410; + mtypes[0] = CKM_GOSTR3410_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2001_PARAMSET_C_OID; + hash_paramset_encoded_oid = GOST_HASH2012_256_PARAMSET_OID; + } + else if (!strcmp("-2012-512:A", p_param_set)) { + gost_key_type = CKK_GOSTR3410_512; + mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_512_PARAMSET_A_OID; + hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; + } + else if (!strcmp("-2012-512:B", p_param_set)) { + gost_key_type = CKK_GOSTR3410_512; + mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_512_PARAMSET_B_OID; + hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; + } + else if (!strcmp("-2012-512:C", p_param_set)) { + gost_key_type = CKK_GOSTR3410_512; + mtypes[0] = CKM_GOSTR3410_512_KEY_PAIR_GEN; + key_paramset_encoded_oid = GOST2012_512_PARAMSET_C_OID; + hash_paramset_encoded_oid = GOST_HASH2012_512_PARAMSET_OID; } else - util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410:A, GOSTR3410:B, GOSTR3410:C", type); + util_fatal("Unknown key type %s, valid key types for mechanism GOSTR3410 are GOSTR3410-2001:{A,B,C}," + " GOSTR3410-2012-256:{A,B,C,D}, GOSTR3410-2012-512:{A,B,C}", type); - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid, sizeof(key_paramset_encoded_oid)); + if (!opt_mechanism_used) { + if (!find_mechanism(slot, CKF_GENERATE_KEY_PAIR, mtypes, mtypes_num, &opt_mechanism)) + util_fatal("Generate GOSTR3410%s mechanism not supported", gost_key_type == CKK_GOSTR3410_512 ? "-2012-512" : ""); + } + + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid.value, key_paramset_encoded_oid.len); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid, sizeof(key_paramset_encoded_oid)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3410_PARAMS, key_paramset_encoded_oid.value, key_paramset_encoded_oid.len); n_privkey_attr++; - FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid)); + FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid.value, hash_paramset_encoded_oid.len); n_pubkey_attr++; - FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid, sizeof(hash_paramset_encoded_oid)); + FILL_ATTR(privateKeyTemplate[n_privkey_attr], CKA_GOSTR3411_PARAMS, hash_paramset_encoded_oid.value, hash_paramset_encoded_oid.len); n_privkey_attr++; FILL_ATTR(publicKeyTemplate[n_pubkey_attr], CKA_KEY_TYPE, &gost_key_type, sizeof(gost_key_type));