Skip to content

Commit

Permalink
feat(pkcs11-tool): add support for RSA OAEP encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreGonzalo committed Jun 12, 2024
1 parent 413c1a2 commit b27acaa
Showing 1 changed file with 83 additions and 132 deletions.
215 changes: 83 additions & 132 deletions src/tools/pkcs11-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -2548,6 +2548,72 @@ static void verify_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
printf("Cryptoki returned error: %s\n", CKR2Str(rv));
}

static void
build_rsa_oaep_params(
CK_RSA_PKCS_OAEP_PARAMS *oaep_params,
CK_MECHANISM *mech,
char *param,
int param_len)
{
/* An RSA-OAEP mechanism needs parameters */

/* set "default" MGF and hash algorithms. We can overwrite MGF later */
oaep_params->hashAlg = opt_hash_alg;
switch (opt_hash_alg) {
case CKM_SHA_1:
oaep_params->mgf = CKG_MGF1_SHA1;
break;
case CKM_SHA224:
oaep_params->mgf = CKG_MGF1_SHA224;
break;
case CKM_SHA3_224:
oaep_params->mgf = CKG_MGF1_SHA3_224;
break;
case CKM_SHA3_256:
oaep_params->mgf = CKG_MGF1_SHA3_256;
break;
case CKM_SHA3_384:
oaep_params->mgf = CKG_MGF1_SHA3_384;
break;
case CKM_SHA3_512:
oaep_params->mgf = CKG_MGF1_SHA3_512;
break;
default:
printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(opt_hash_alg));
oaep_params->hashAlg = CKM_SHA256;
/* fall through */
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;
}

if (opt_mgf != 0) {
oaep_params->mgf = opt_mgf;
} else {
printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(oaep_params->mgf));
}

oaep_params->source = CKZ_DATA_SPECIFIED;
oaep_params->pSourceData = param;
oaep_params->ulSourceDataLen = param_len;

mech->pParameter = oaep_params;
mech->ulParameterLen = sizeof(*oaep_params);

printf("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);
}

static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE key)
{
Expand All @@ -2568,7 +2634,6 @@ 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 "
Expand All @@ -2578,39 +2643,7 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
/* 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_SHA_1:
oaep_params.mgf = CKG_MGF1_SHA1;
break;
case CKM_SHA224:
oaep_params.mgf = CKG_MGF1_SHA224;
break;
case CKM_SHA3_224:
oaep_params.mgf = CKG_MGF1_SHA3_224;
break;
case CKM_SHA3_256:
oaep_params.mgf = CKG_MGF1_SHA3_256;
break;
case CKM_SHA3_384:
oaep_params.mgf = CKG_MGF1_SHA3_384;
break;
case CKM_SHA3_512:
oaep_params.mgf = CKG_MGF1_SHA3_512;
break;
default:
oaep_params.hashAlg = CKM_SHA256;
/* fall through */
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;
}
build_rsa_oaep_params(&oaep_params, &mech, NULL, 0);
break;
case CKM_RSA_X_509:
case CKM_RSA_PKCS:
Expand All @@ -2629,29 +2662,6 @@ static void decrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
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);

}

if (opt_input == NULL)
fd_in = 0;
else if ((fd_in = open(opt_input, O_RDONLY | O_BINARY)) < 0)
Expand Down Expand Up @@ -2722,6 +2732,7 @@ static void encrypt_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_in, fd_out;
ssize_t sz;
Expand All @@ -2736,7 +2747,14 @@ static void encrypt_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
memset(&mech, 0, sizeof(mech));
mech.mechanism = opt_mechanism;

if (opt_hash_alg != 0 && opt_mechanism != CKM_RSA_PKCS_OAEP)
util_fatal("The hash-algorithm is applicable only to "
"RSA-PKCS-OAEP mechanism");

switch (opt_mechanism) {
case CKM_RSA_PKCS_OAEP:
build_rsa_oaep_params(&oaep_params, &mech, NULL, 0);
break;
case CKM_AES_ECB:
mech.pParameter = NULL;
mech.ulParameterLen = 0;
Expand Down Expand Up @@ -7400,8 +7418,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
CK_ULONG encrypted_len, data_len;
int failed;
CK_RV rv;
int pad;
CK_MECHANISM_TYPE hash_alg = CKM_SHA256;
int pad;
CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA256;
CK_RSA_PKCS_OAEP_PARAMS oaep_params;

Expand Down Expand Up @@ -7429,50 +7446,11 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
max_in_len = mod_len-11;
in_len = 10;
break;
case CKM_RSA_PKCS_OAEP: {
if (opt_hash_alg != 0) {
hash_alg = opt_hash_alg;
}
switch (hash_alg) {
case CKM_SHA_1:
mgf = CKG_MGF1_SHA1;
break;
case CKM_SHA224:
mgf = CKG_MGF1_SHA224;
break;
default:
printf("hash-algorithm %s unknown, defaulting to CKM_SHA256\n", p11_mechanism_to_name(hash_alg));
/* fall through */
case CKM_SHA256:
mgf = CKG_MGF1_SHA256;
break;
case CKM_SHA384:
mgf = CKG_MGF1_SHA384;
break;
case CKM_SHA512:
mgf = CKG_MGF1_SHA512;
break;
case CKM_SHA3_224:
mgf = CKG_MGF1_SHA3_224;
break;
case CKM_SHA3_256:
mgf = CKG_MGF1_SHA3_256;
break;
case CKM_SHA3_384:
mgf = CKG_MGF1_SHA3_384;
break;
case CKM_SHA3_512:
mgf = CKG_MGF1_SHA3_512;
break;
}
if (opt_mgf != 0) {
mgf = opt_mgf;
} else {
printf("mgf not set, defaulting to %s\n", p11_mgf_to_name(mgf));
}
case CKM_RSA_PKCS_OAEP:
build_rsa_oaep_params(&oaep_params, &mech, param, param_len);

pad = RSA_PKCS1_OAEP_PADDING;
size_t len = 2+2*hash_length(hash_alg);
size_t len = 2 + 2 * hash_length(oaep_params.hashAlg);
if (len >= mod_len) {
printf("Incompatible mechanism and key size\n");
return 0;
Expand All @@ -7481,7 +7459,6 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
max_in_len = mod_len-len;
in_len = 10;
break;
}
case CKM_RSA_X_509:
pad = RSA_NO_PADDING;
/* input length equals modulus length */
Expand Down Expand Up @@ -7528,15 +7505,15 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
if (mech_type == CKM_RSA_PKCS_OAEP) {
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
const EVP_MD *md;
switch (hash_alg) {
switch (oaep_params.hashAlg) {
case CKM_SHA_1:
md = EVP_sha1();
break;
case CKM_SHA224:
md = EVP_sha224();
break;
default: /* it should not happen, hash_alg is checked earlier */
/* fall through */
default: /* it should not happen, oaep_params.hashAlg is checked earlier */
/* fall through */
case CKM_SHA256:
md = EVP_sha256();
break;
Expand Down Expand Up @@ -7617,7 +7594,7 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
}
}
#else
if (hash_alg != CKM_SHA_1) {
if (oaep_params.hashAlg != CKM_SHA_1) {
printf("This version of OpenSSL only supports SHA1 for OAEP, returning\n");
return 0;
}
Expand All @@ -7635,34 +7612,8 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
EVP_PKEY_free(pkey);
encrypted_len = out_len;

/* set "default" MGF and hash algorithms. We can overwrite MGF later */
switch (mech_type) {
case CKM_RSA_PKCS_OAEP:
oaep_params.hashAlg = hash_alg;
oaep_params.mgf = mgf;

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 */

fprintf(stderr, "OAEP parameters: hashAlg=%s, mgf=%s, ",
p11_mechanism_to_name(oaep_params.hashAlg),
p11_mgf_to_name(oaep_params.mgf));

if (param != NULL && param_len > 0) {
oaep_params.source = CKZ_DATA_SPECIFIED;
oaep_params.pSourceData = param;
oaep_params.ulSourceDataLen = param_len;
fprintf(stderr, "encoding parameter (Label) present, length %d\n", param_len);
} else {
fprintf(stderr, "encoding parameter (Label) not present\n");
}

mech.pParameter = &oaep_params;
mech.ulParameterLen = sizeof(oaep_params);



break;
case CKM_RSA_X_509:
case CKM_RSA_PKCS:
Expand Down

0 comments on commit b27acaa

Please sign in to comment.