diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2019-02-04 11:27:45 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2019-02-04 11:27:45 -0500 |
commit | 4f9a710b2d235527dd80013ef5207b93b782ab00 (patch) | |
tree | 88c267dede8d74f10ce1b9674ee2c81d61ffe9a6 | |
parent | a7fd0645171be45fe51e847b79f9067ad5c3e578 (diff) | |
download | openssl-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.c | 74 |
1 files changed, 73 insertions, 1 deletions
@@ -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); |