Skip to content

Commit

Permalink
Add basic support for OEAP decryption in OpenSC internals
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakuje committed Jan 7, 2020
1 parent 40c41ce commit 3a3a465
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/libopensc/opensc.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,13 @@ extern "C" {
* must support at least one of them, and exactly one of them must be selected
* for a given operation. */
#define SC_ALGORITHM_RSA_RAW 0x00000001
#define SC_ALGORITHM_RSA_PADS 0x0000001F
#define SC_ALGORITHM_RSA_PADS 0x0000002F
#define SC_ALGORITHM_RSA_PAD_NONE 0x00000001
#define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */
#define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004
#define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008
#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */
#define SC_ALGORITHM_RSA_PAD_OAEP 0x00000020 /* PKCS#1 v2.0 OAEP */

/* If the card is willing to produce a cryptogram with the following
* hash values, set these flags accordingly. The interpretation of the hash
Expand Down
1 change: 1 addition & 0 deletions src/libopensc/padding.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ int sc_get_encoding_flags(sc_context_t *ctx,
/* Use the card's raw RSA capability on the padded input */
*sflags = SC_ALGORITHM_RSA_PAD_NONE;
*pflags = iflags;
/* TODO emulate the OAEP decryption */

} else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
(iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) {
Expand Down
70 changes: 69 additions & 1 deletion src/pkcs11/framework-pkcs15.c
Original file line number Diff line number Diff line change
Expand Up @@ -3976,7 +3976,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
/* Check the data length matches the selected hash */
rv = pkcs15_prkey_check_pss_param(pMechanism, (int)ulDataLen);
if (rv != CKR_OK) {
sc_log(context, "Invalid data lenght for the selected "
sc_log(context, "Invalid data length for the selected "
"PSS parameters");
return rv;
}
Expand Down Expand Up @@ -4179,6 +4179,39 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
case CKM_RSA_X_509:
flags |= SC_ALGORITHM_RSA_RAW;
break;
case CKM_RSA_PKCS_OAEP:
flags |= SC_ALGORITHM_RSA_PAD_OAEP;

/* Omited parameter can use MGF1-SHA1 and SHA1 hash ? */
if (pMechanism->pParameter == NULL) {
flags |= SC_ALGORITHM_RSA_HASH_SHA1;
flags |= SC_ALGORITHM_MGF1_SHA1;
break;
}

switch (((CK_RSA_PKCS_OAEP_PARAMS*)pMechanism->pParameter)->hashAlg) {
case CKM_SHA_1:
flags |= SC_ALGORITHM_RSA_HASH_SHA1;
break;
case CKM_SHA224:
flags |= SC_ALGORITHM_RSA_HASH_SHA224;
break;
case CKM_SHA256:
flags |= SC_ALGORITHM_RSA_HASH_SHA256;
break;
case CKM_SHA384:
flags |= SC_ALGORITHM_RSA_HASH_SHA384;
break;
case CKM_SHA512:
flags |= SC_ALGORITHM_RSA_HASH_SHA512;
break;
default:
return CKR_MECHANISM_PARAM_INVALID;
}

/* The MGF parameter was already verified in SignInit() */
flags |= mgf2flags(((CK_RSA_PKCS_OAEP_PARAMS*)pMechanism->pParameter)->mgf);
break;
default:
return CKR_MECHANISM_INVALID;
}
Expand Down Expand Up @@ -4352,6 +4385,7 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session,
const unsigned int salt_lens[5] = { 160, 256, 384, 512, 224 };
const unsigned int hashes[5] = { CKM_SHA_1, CKM_SHA256,
CKM_SHA384, CKM_SHA512, CKM_SHA224 };
const CK_RSA_PKCS_OAEP_PARAMS *oaep_params;

switch (pMechanism->mechanism) {
case CKM_RSA_PKCS_PSS:
Expand Down Expand Up @@ -4407,6 +4441,26 @@ pkcs15_prkey_init_params(struct sc_pkcs11_session *session,

/* TODO support different salt lengths */
break;
case CKM_RSA_PKCS_OAEP:
if (!pMechanism->pParameter ||
pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS))
return CKR_MECHANISM_PARAM_INVALID;

oaep_params = (CK_RSA_PKCS_OAEP_PARAMS*)pMechanism->pParameter;
switch (oaep_params->mgf) {
case CKG_MGF1_SHA1:
case CKG_MGF1_SHA224:
case CKG_MGF1_SHA256:
case CKG_MGF1_SHA384:
case CKG_MGF1_SHA512:
/* OK */
break;
default:
return CKR_MECHANISM_PARAM_INVALID;
}
/* TODO support different salt lengths */
/* TODO is there something more to check */
break;
}
return CKR_OK;
}
Expand Down Expand Up @@ -5619,6 +5673,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
rsa_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
#ifdef ENABLE_OPENSSL
rsa_flags |= SC_ALGORITHM_RSA_PAD_PSS;
/* TODO support OAEP decryption & encryption using OpenSSL */
#endif
}

Expand Down Expand Up @@ -5699,6 +5754,7 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
}

if (rsa_flags & SC_ALGORITHM_RSA_PAD_PSS) {
CK_FLAGS old_flags = mech_info.flags;
mech_info.flags &= ~(CKF_DECRYPT|CKF_ENCRYPT);
mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_PSS, &mech_info, CKK_RSA, NULL, NULL);
rc = sc_pkcs11_register_mechanism(p11card, mt);
Expand Down Expand Up @@ -5735,6 +5791,18 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
if (rc != CKR_OK)
return rc;
}
mech_info.flags = old_flags;
}

if (rsa_flags & SC_ALGORITHM_RSA_PAD_OAEP) {
CK_FLAGS old_flags = mech_info.flags;
mech_info.flags &= ~(CKF_SIGN|CKF_VERIFY|CKF_SIGN_RECOVER|CKF_VERIFY_RECOVER);
mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_OAEP, &mech_info, CKK_RSA, NULL, NULL);
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK) {
return rc;
}
mech_info.flags = old_flags;
}

if (rsa_flags & SC_ALGORITHM_ONBOARD_KEY_GEN) {
Expand Down
9 changes: 9 additions & 0 deletions src/pkcs11/mechanism.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,15 @@ sc_pkcs11_decr_init(struct sc_pkcs11_session *session,
}
rv = mt->decrypt_init(operation, key);

/* Validate the mechanism parameters */
if (key->ops->init_params) {
rv = key->ops->init_params(operation->session, &operation->mechanism);
if (rv != CKR_OK) {
/* Probably bad arguments */
LOG_FUNC_RETURN(context, (int) rv);
}
}

if (rv != CKR_OK)
session_stop_operation(session, SC_PKCS11_OPERATION_DECRYPT);

Expand Down
1 change: 1 addition & 0 deletions src/tools/opensc-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ static int list_algorithms(void)
{ SC_ALGORITHM_RSA_PAD_PKCS1, "pkcs1" },
{ SC_ALGORITHM_RSA_PAD_ANSI, "ansi" },
{ SC_ALGORITHM_RSA_PAD_PSS, "pss" },
{ SC_ALGORITHM_RSA_PAD_OAEP, "oaep" },
{ SC_ALGORITHM_RSA_PAD_ISO9796, "iso9796" },
{ SC_ALGORITHM_RSA_HASH_SHA1, "sha1" },
{ SC_ALGORITHM_RSA_HASH_MD5, "MD5" },
Expand Down

0 comments on commit 3a3a465

Please sign in to comment.