Add support in pkcs11-tool and pkcs11-spy for RSA-OAEP (#1169)
* Add RSA-OAEP documentation * Add definitions and structures needed for RSA-OAEP * Add ability to display RSA-OAEP parameters to SPY Closes https://github.com/OpenSC/OpenSC/issues/1170
This commit is contained in:
parent
391b32c378
commit
e4c589639d
@ -75,8 +75,22 @@
|
||||
<term>
|
||||
<option>--hash-algorithm</option> <replaceable>mechanism</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify hash algorithm used with
|
||||
RSA-PKCS-PSS signature. Default is SHA-1.</para></listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify hash algorithm used with RSA-PKCS-PSS signature or RSA-OAEP decryption.
|
||||
Allowed values are "SHA-1", "SHA256", "SHA384", "SHA512", and some tokens may
|
||||
also allow "SHA224". Default is "SHA-1".
|
||||
</para>
|
||||
<para>
|
||||
Note that the input to RSA-PKCS-PSS has to be of the size equal to
|
||||
the specified hash algorithm. E.g., for SHA256 the signature input must
|
||||
be exactly 32 bytes long (for mechanisms SHA256-RSA-PKCS-PSS there is no
|
||||
such restriction). For RSA-OAEP, the plaintext input size mLen must be
|
||||
at most keyLen - 2 - 2*hashLen. For example, for RSA 3072-bit key and
|
||||
SHA384, the longest plaintext to encrypt with RSA-OAEP is (with all
|
||||
sizes in bytes): 384 - 2 - 2*48 = 286, aka 286 bytes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -226,9 +240,10 @@
|
||||
</term>
|
||||
<listitem><para>Use the specified Message Generation
|
||||
Function (MGF) <replaceable>function</replaceable>
|
||||
for RSA-PSS signatures. Supported arguments are MGF1-SHA1
|
||||
for RSA-PKCS-PSS signatures or RSA-OAEP decryptions. Supported arguments are MGF1-SHA1
|
||||
to MGF1-SHA512 if supported by the driver.
|
||||
The default is based on the hash selection.</para></listitem>
|
||||
The default is based on the hash selection.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -844,6 +844,26 @@ C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT
|
||||
enter("C_DecryptInit");
|
||||
spy_dump_ulong_in("hSession", hSession);
|
||||
fprintf(spy_output, "pMechanism->type=%s\n", lookup_enum(MEC_T, pMechanism->mechanism));
|
||||
switch (pMechanism->mechanism) {
|
||||
case CKM_RSA_PKCS_OAEP:
|
||||
if (pMechanism->pParameter != NULL) {
|
||||
CK_RSA_PKCS_OAEP_PARAMS *param =
|
||||
(CK_RSA_PKCS_OAEP_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->source=%lu\n", param->source);
|
||||
spy_dump_string_out("pSourceData[ulSourceDalaLen]",
|
||||
param->pSourceData, param->ulSourceDataLen);
|
||||
} else {
|
||||
fprintf(spy_output, "Parameters block for %s is empty...\n",
|
||||
lookup_enum(MEC_T, pMechanism->mechanism));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
spy_dump_ulong_in("hKey", hKey);
|
||||
rv = po->C_DecryptInit(hSession, pMechanism, hKey);
|
||||
return retne(rv);
|
||||
@ -984,6 +1004,9 @@ C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HA
|
||||
lookup_enum(MGF_T, param->mgf));
|
||||
fprintf(spy_output, "pMechanism->pParameter->sLen=%lu\n",
|
||||
param->sLen);
|
||||
} else {
|
||||
fprintf(spy_output, "Parameters block for %s is empty...\n",
|
||||
lookup_enum(MEC_T, pMechanism->mechanism));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -764,6 +764,16 @@ typedef struct CK_ECDH1_DERIVE_PARAMS {
|
||||
unsigned char * pPublicData;
|
||||
} CK_ECDH1_DERIVE_PARAMS;
|
||||
|
||||
typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE;
|
||||
|
||||
typedef struct CK_RSA_PKCS_OAEP_PARAMS {
|
||||
CK_MECHANISM_TYPE hashAlg;
|
||||
CK_RSA_PKCS_MGF_TYPE mgf;
|
||||
CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
|
||||
void *pSourceData;
|
||||
unsigned long ulSourceDataLen;
|
||||
} CK_RSA_PKCS_OAEP_PARAMS;
|
||||
|
||||
typedef struct CK_RSA_PKCS_PSS_PARAMS {
|
||||
ck_mechanism_type_t hashAlg;
|
||||
unsigned long mgf;
|
||||
|
@ -235,8 +235,8 @@ 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 RSA-PKCS-PSS signature",
|
||||
"Specify MGF (Message Generation Function) used for RSA-PSS signatures (possible values are MGF1-SHA1 to MGF1-SHA512)",
|
||||
"Specify hash algorithm used with RSA-PKCS-PSS signature and RSA-PKCS-OAEP decryption",
|
||||
"Specify MGF (Message Generation Function) used for RSA-PSS signature and RSA-OAEP decryption (possible values are MGF1-SHA1 to MGF1-SHA512)",
|
||||
"Specify how many bytes should be used for salt in RSA-PSS signatures (default is digest size)",
|
||||
|
||||
"Log into the token first",
|
||||
@ -1692,6 +1692,9 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
||||
pss_params.hashAlg = opt_hash_alg;
|
||||
|
||||
switch (opt_hash_alg) {
|
||||
case CKM_SHA224:
|
||||
pss_params.mgf = CKG_MGF1_SHA224;
|
||||
break;
|
||||
case CKM_SHA256:
|
||||
pss_params.mgf = CKG_MGF1_SHA256;
|
||||
break;
|
||||
@ -1715,6 +1718,11 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
||||
pss_params.mgf = CKG_MGF1_SHA1;
|
||||
break;
|
||||
|
||||
case CKM_SHA224_RSA_PKCS_PSS:
|
||||
pss_params.hashAlg = CKM_SHA224;
|
||||
pss_params.mgf = CKG_MGF1_SHA224;
|
||||
break;
|
||||
|
||||
case CKM_SHA256_RSA_PKCS_PSS:
|
||||
pss_params.hashAlg = CKM_SHA256;
|
||||
pss_params.mgf = CKG_MGF1_SHA256;
|
||||
@ -1762,7 +1770,8 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \
|
||||
|
||||
mech.pParameter = &pss_params;
|
||||
mech.ulParameterLen = sizeof(pss_params);
|
||||
fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt=%lu B\n",
|
||||
|
||||
fprintf(stderr, "PSS parameters: hashAlg=%s, mgf=%s, salt_len=%lu B\n",
|
||||
p11_mechanism_to_name(pss_params.hashAlg),
|
||||
p11_mgf_to_name(pss_params.mgf),
|
||||
pss_params.sLen);
|
||||
@ -1777,6 +1786,10 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \
|
||||
if (r < 0)
|
||||
util_fatal("Cannot read from %s: %m", opt_input);
|
||||
|
||||
if (opt_mechanism == CKM_RSA_PKCS_PSS && (unsigned long)r != hashlen)
|
||||
util_fatal("For %s mechanism, message size (got %d bytes) must be equal to specified digest length (%lu)\n",
|
||||
p11_mechanism_to_name(opt_mechanism), r, hashlen);
|
||||
|
||||
rv = CKR_CANCEL;
|
||||
if (r < (int) sizeof(in_buffer)) {
|
||||
rv = p11->C_SignInit(session, &mech, key);
|
||||
@ -1819,7 +1832,7 @@ to zero, or equal to -1 (meaning: use digest size) or to -2 \
|
||||
util_fatal("failed to open %s: %m", opt_output);
|
||||
}
|
||||
|
||||
if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512) {
|
||||
if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1 || opt_mechanism == CKM_ECDSA_SHA256 || opt_mechanism == CKM_ECDSA_SHA384 || opt_mechanism == CKM_ECDSA_SHA512 || opt_mechanism == CKM_ECDSA_SHA224) {
|
||||
if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) {
|
||||
unsigned char *seq;
|
||||
size_t seqlen;
|
||||
@ -1849,6 +1862,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
||||
unsigned char in_buffer[1024], out_buffer[1024];
|
||||
CK_MECHANISM mech;
|
||||
CK_RV rv;
|
||||
CK_RSA_PKCS_OAEP_PARAMS oaep_params;
|
||||
CK_ULONG in_len, out_len;
|
||||
int fd, r;
|
||||
|
||||
@ -1859,6 +1873,11 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
||||
fprintf(stderr, "Using decrypt algorithm %s\n", p11_mechanism_to_name(opt_mechanism));
|
||||
memset(&mech, 0, sizeof(mech));
|
||||
mech.mechanism = opt_mechanism;
|
||||
oaep_params.hashAlg = 0;
|
||||
|
||||
if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP)
|
||||
util_fatal("The hash-algorithm is applicable only to "
|
||||
"RSA-PKCS-OAEP mechanism");
|
||||
|
||||
if (opt_input == NULL)
|
||||
fd = 0;
|
||||
@ -1870,6 +1889,62 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
||||
util_fatal("Cannot read from %s: %m", opt_input);
|
||||
in_len = r;
|
||||
|
||||
/* set "default" MGF and hash algorithms. We can overwrite MGF later */
|
||||
switch (opt_mechanism) {
|
||||
case CKM_RSA_PKCS_OAEP:
|
||||
oaep_params.hashAlg = opt_hash_alg;
|
||||
switch (opt_hash_alg) {
|
||||
case CKM_SHA224:
|
||||
oaep_params.mgf = CKG_MGF1_SHA224;
|
||||
break;
|
||||
case CKM_SHA256:
|
||||
oaep_params.mgf = CKG_MGF1_SHA256;
|
||||
break;
|
||||
case CKM_SHA384:
|
||||
oaep_params.mgf = CKG_MGF1_SHA384;
|
||||
break;
|
||||
case CKM_SHA512:
|
||||
oaep_params.mgf = CKG_MGF1_SHA512;
|
||||
break;
|
||||
default:
|
||||
oaep_params.hashAlg = CKM_SHA_1;
|
||||
/* fallthrough to SHA-1 default */
|
||||
case CKM_SHA_1:
|
||||
oaep_params.mgf = CKG_MGF1_SHA1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CKM_RSA_PKCS:
|
||||
mech.pParameter = NULL;
|
||||
mech.ulParameterLen = 0;
|
||||
break;
|
||||
default:
|
||||
util_fatal("Mechanism %s illegal or not supported\n", p11_mechanism_to_name(opt_mechanism));
|
||||
}
|
||||
|
||||
|
||||
/* If an RSA-OAEP mechanism, it needs parameters */
|
||||
if (oaep_params.hashAlg) {
|
||||
if (opt_mgf != 0)
|
||||
oaep_params.mgf = opt_mgf;
|
||||
|
||||
/* These settings are compatible with OpenSSL 1.0.2L and 1.1.0+ */
|
||||
oaep_params.source = 0UL; /* empty encoding parameter (label) */
|
||||
oaep_params.pSourceData = NULL; /* PKCS#11 standard: this must be NULLPTR */
|
||||
oaep_params.ulSourceDataLen = 0; /* PKCS#11 standard: this must be 0 */
|
||||
|
||||
mech.pParameter = &oaep_params;
|
||||
mech.ulParameterLen = sizeof(oaep_params);
|
||||
|
||||
fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, source_type=%lu, source_ptr=%p, source_len=%lu\n",
|
||||
p11_mechanism_to_name(oaep_params.hashAlg),
|
||||
p11_mgf_to_name(oaep_params.mgf),
|
||||
oaep_params.source,
|
||||
oaep_params.pSourceData,
|
||||
oaep_params.ulSourceDataLen);
|
||||
|
||||
}
|
||||
|
||||
rv = p11->C_DecryptInit(session, &mech, key);
|
||||
if (rv != CKR_OK)
|
||||
p11_fatal("C_DecryptInit", rv);
|
||||
@ -5781,6 +5856,7 @@ static struct mech_info p11_mechanisms[] = {
|
||||
{ CKM_MD2_RSA_PKCS, "MD2-RSA-PKCS", NULL },
|
||||
{ CKM_MD5_RSA_PKCS, "MD5-RSA-PKCS", "rsa-md5" },
|
||||
{ CKM_SHA1_RSA_PKCS, "SHA1-RSA-PKCS", "rsa-sha1" },
|
||||
{ CKM_SHA224_RSA_PKCS, "SHA224-RSA-PKCS", "rsa-sha224" },
|
||||
{ CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS", "rsa-sha256" },
|
||||
{ CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS", "rsa-sha384" },
|
||||
{ CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS", "rsa-sha512" },
|
||||
@ -5792,6 +5868,7 @@ static struct mech_info p11_mechanisms[] = {
|
||||
{ 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", "rsa-pss-sha1" },
|
||||
{ CKM_SHA224_RSA_PKCS_PSS,"SHA224-RSA-PKCS-PSS", "rsa-pss-sha224" },
|
||||
{ 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" },
|
||||
@ -5840,6 +5917,8 @@ static struct mech_info p11_mechanisms[] = {
|
||||
{ CKM_SHA_1, "SHA-1", NULL },
|
||||
{ CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL },
|
||||
{ CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL },
|
||||
{ CKM_SHA224, "SHA224", NULL },
|
||||
{ CKM_SHA224_HMAC, "SHA224-HMAC", NULL },
|
||||
{ CKM_SHA256, "SHA256", NULL },
|
||||
{ CKM_SHA256_HMAC, "SHA256-HMAC", NULL },
|
||||
{ CKM_SHA384, "SHA384", NULL },
|
||||
|
Loading…
Reference in New Issue
Block a user