aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2019-02-04 11:27:45 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2019-02-04 11:27:45 -0500
commit4f9a710b2d235527dd80013ef5207b93b782ab00 (patch)
tree88c267dede8d74f10ce1b9674ee2c81d61ffe9a6
parenta7fd0645171be45fe51e847b79f9067ad5c3e578 (diff)
downloadopenssl-pkcs11-export-4f9a710b2d235527dd80013ef5207b93b782ab00.tar.gz
crypto: add support for PSS and OAEP signing and encryption schemes
Somewhat problematic because various versions of openssl have different levels of support for this, but 1.1.0 supports them fully. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--crypto.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/crypto.c b/crypto.c
index 7baab5d..8f7311e 100644
--- a/crypto.c
+++ b/crypto.c
@@ -161,18 +161,88 @@ static EVP_PKEY_CTX *get_key(int sec_num)
return ctx;
}
+const EVP_MD *get_mgf1(unsigned long mgf1)
+{
+ switch (mgf1) {
+ case CKG_MGF1_SHA1:
+ return EVP_sha1();
+ case CKG_MGF1_SHA224:
+ return EVP_sha224();
+ case CKG_MGF1_SHA256:
+ return EVP_sha256();
+ case CKG_MGF1_SHA384:
+ return EVP_sha384();
+ case CKG_MGF1_SHA512:
+ return EVP_sha512();
+ default:
+ fprintf(stderr, "Unknown mgf1 type %ld\n", mgf1);
+ return NULL;
+ }
+}
+
+const EVP_MD *get_hash(unsigned long hash)
+{
+ switch (hash) {
+ case CKM_SHA_1:
+ return EVP_sha1();
+ case CKM_SHA224:
+ return EVP_sha224();
+ case CKM_SHA256:
+ return EVP_sha256();
+ case CKM_SHA384:
+ return EVP_sha384();
+ case CKM_SHA512:
+ return EVP_sha512();
+ default:
+ fprintf(stderr, "Unknown hash type %ld\n", hash);
+ return NULL;
+ }
+}
+
static EVP_PKEY_CTX *add_padding(EVP_PKEY_CTX *ctx, CK_MECHANISM_PTR mech)
{
if (mech->mechanism == CKM_RSA_PKCS) {
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
} else if (mech->mechanism == CKM_RSA_X_509) {
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING);
+ } else if (mech->mechanism == CKM_RSA_PKCS_PSS) {
+ CK_RSA_PKCS_PSS_PARAMS *p = mech->pParameter;
+
+ if (mech->ulParameterLen != sizeof(*p)) {
+ fprintf(stderr, "PSS mechanism parameter length %ld != %ld\n",
+ mech->ulParameterLen, sizeof(*p));
+ goto err;
+ }
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING);
+ EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, get_mgf1(p->mgf));
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, p->sLen);
+ } else if (mech->mechanism == CKM_RSA_PKCS_OAEP) {
+ struct CK_RSA_PKCS_OAEP_PARAMS *p = mech->pParameter;
+
+ if (mech->ulParameterLen != sizeof(*p)) {
+ fprintf(stderr, "OAEP mechanism parameter length %ld != %ld\n",
+ mech->ulParameterLen, sizeof(*p));
+ goto err;
+ }
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
+ EVP_PKEY_CTX_set_rsa_oaep_md(ctx, get_hash(p->hashAlg));
+ EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, get_mgf1(p->mgf));
+ if (p->source & CKZ_DATA_SPECIFIED) {
+ void *l = OPENSSL_memdup(p->pSourceData,
+ p->ulSourceDataLen);
+
+ EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l,
+ p->ulSourceDataLen);
+ }
} else {
fprintf(stderr, "unknown mechanism %ld\n", mech->mechanism);
- return NULL;
+ goto err;
}
return ctx;
+ err:
+ EVP_PKEY_CTX_free(ctx);
+ return NULL;
}
void *crypto_sign_init(int sec_num, CK_MECHANISM_PTR mech)
@@ -231,6 +301,8 @@ void crypto_fill_mechanism_list(int sec_num, unsigned long *mechs,
CK_MECHANISM_TYPE types[] = {
CKM_RSA_PKCS,
CKM_RSA_X_509,
+ CKM_RSA_PKCS_PSS,
+ CKM_RSA_PKCS_OAEP,
};
*count = ARRAY_SIZE(types);