Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement implicit rejection for RSA PKCS#1 v1.5 de-padding #737

Merged
merged 3 commits into from Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 12 additions & 2 deletions COPYRIGHTS
Expand Up @@ -12,19 +12,29 @@ For code originating from OpenSSL:
* Note that in OpenSSL the file crypto/bn/rsa_sup_mul.c does no longer
* exist, it was removed with commit https://github.com/openssl/openssl/commit/4209ce68d8fe8b1506494efa03d378d05baf9ff8
* - usr/lib/common/constant_time.h: Copied unchanged from OpenSSL from
include/internal/constant_time.h
* include/internal/constant_time.h
* - The implementation of function rsa_parse_block_type_2() in
* usr/lib/common/mech_rsa.c is copied from OpenSSL's function
* ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
* See comment in function rsa_parse_block_type_2() for a list of changes.
* - The implementation of function openssl_specific_rsa_derive_kdk() in
* usr/lib/common/mech_openssl.c is copied from OpenSSL's function
* derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to
* the OpenCryptoki environment. See comment in function
* openssl_specific_rsa_derive_kdk() for a list of changes.
* - The implementation of function openssl_specific_rsa_prf() in
* usr/lib/common/mech_openssl.c is copied from OpenSSL's function
* ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to
* the OpenCryptoki environment. See comment in function
* openssl_specific_rsa_prf() for a list of changes.
* - The implementation of function decode_eme_oaep() in
* usr/lib/common/mech_rsa.c is copied from OpenSSL's function
* RSA_padding_check_PKCS1_OAEP_mgf1() in crypto/rsa/rsa_oaep.c and is
* slightly modified to fit to the OpenCryptoki environment. See comment in
* function decode_eme_oaep() for a list of changes.
*
* Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* The OpenSSL code is licensed under the Apache License 2.0 (the "License").
* You can obtain a copy in the file LICENSE in the OpenSSL source distribution
Expand Down
814 changes: 814 additions & 0 deletions testcases/crypto/rsa.h

Large diffs are not rendered by default.

165 changes: 165 additions & 0 deletions testcases/crypto/rsa_func.c
Expand Up @@ -1963,6 +1963,164 @@ CK_RV do_VerifyRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite)
return rc;
}

CK_RV do_RSAImplicitRejection(struct PUBLISHED_TEST_SUITE_INFO *tsuite)
{
unsigned int i;
CK_BYTE decrypt[BIG_REQUEST];
CK_ULONG decrypt_len;
CK_MECHANISM mech;
CK_OBJECT_HANDLE priv_key = CK_INVALID_HANDLE;
CK_SLOT_ID slot_id = SLOT_ID;
CK_SESSION_HANDLE session;
CK_FLAGS flags;
CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
CK_ULONG user_pin_len;
CK_RV rc, loc_rc;

char *s;

// begin testsuite
testsuite_begin("%s Implicit Rejection.", tsuite->name);
testcase_rw_session();
testcase_user_login();

if (!is_ica_token(slot_id) && !is_soft_token(slot_id)) {
testsuite_skip(tsuite->tvcount,
"Slot %u doesn't support Implicit Rejection",
(unsigned int) slot_id);
goto testcase_cleanup;
}
// skip tests if the slot doesn't support this mechanism
if (!mech_supported(slot_id, tsuite->mech.mechanism)) {
testsuite_skip(tsuite->tvcount,
"Slot %u doesn't support %s (0x%x)",
(unsigned int) slot_id,
mech_to_str(tsuite->mech.mechanism),
(unsigned int) tsuite->mech.mechanism);
goto testcase_cleanup;
}

// iterate over test vectors
for (i = 0; i < tsuite->tvcount; i++) {

// get public exponent from test vector
if (p11_ahex_dump(&s, tsuite->tv[i].pub_exp,
tsuite->tv[i].pubexp_len) == NULL) {
testcase_error("p11_ahex_dump() failed");
rc = -1;
goto testcase_cleanup;
}
// begin testcase
testcase_begin("%s Implicit Rejection with test vector %u."
"\npubl_exp='%s', modbits=%lu, publ_exp_len=%lu.",
tsuite->name, i, s,
tsuite->tv[i].mod_len * 8,
tsuite->tv[i].pubexp_len);

rc = CKR_OK;

if (!keysize_supported(slot_id, tsuite->mech.mechanism,
tsuite->tv[i].mod_len * 8)) {
testcase_skip("Token in slot %lu cannot be used with modbits='%lu'",
SLOT_ID, tsuite->tv[i].mod_len * 8);
free(s);
continue;
}

free(s);

// clear buffers
memset(decrypt, 0, BIG_REQUEST);

// create (private) key handle
rc = create_RSAPrivateKey(session,
tsuite->tv[i].mod,
tsuite->tv[i].pub_exp,
tsuite->tv[i].priv_exp,
tsuite->tv[i].prime1,
tsuite->tv[i].prime2,
tsuite->tv[i].exp1,
tsuite->tv[i].exp2,
tsuite->tv[i].coef,
tsuite->tv[i].mod_len,
tsuite->tv[i].pubexp_len,
tsuite->tv[i].privexp_len,
tsuite->tv[i].prime1_len,
tsuite->tv[i].prime2_len,
tsuite->tv[i].exp1_len,
tsuite->tv[i].exp2_len,
tsuite->tv[i].coef_len, &priv_key);
if (rc != CKR_OK) {
if (rc == CKR_POLICY_VIOLATION) {
testcase_skip("RSA key import is not allowed by policy");
continue;
}

testcase_error("create_RSAPrivateKey(), rc=%s", p11_get_ckr(rc));
goto error;
}

// set cipher buffer length
decrypt_len = BIG_REQUEST;

// get mech
mech = tsuite->mech;

// initialize (private key) decryption
rc = funcs->C_DecryptInit(session, &mech, priv_key);
if (rc != CKR_OK) {
testcase_error("C_DecryptInit, rc=%s", p11_get_ckr(rc));
goto tv_cleanup;
}
// do (private key) decryption
rc = funcs->C_Decrypt(session, tsuite->tv[i].msg, tsuite->tv[i].msg_len,
decrypt, &decrypt_len);
if (rc != CKR_OK) {
testcase_error("C_Decrypt, rc=%s", p11_get_ckr(rc));
goto tv_cleanup;
}

// check results
testcase_new_assertion();

if (decrypt_len != tsuite->tv[i].sig_len) {
testcase_fail("decrypted length does not match"
"expected data length.\n expected length = %lu, "
"but found length=%lu.\n",
tsuite->tv[i].sig_len, decrypt_len);
} else if (memcmp(decrypt, tsuite->tv[i].sig, tsuite->tv[i].sig_len)) {
testcase_fail("decrypted data does not match expected data.");
} else {
testcase_pass("Implicit Rejection.");
}

// clean up
tv_cleanup:

rc = funcs->C_DestroyObject(session, priv_key);
if (rc != CKR_OK) {
testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc));
goto error;
}
}

goto testcase_cleanup;
error:
loc_rc = funcs->C_DestroyObject(session, priv_key);
if (loc_rc != CKR_OK) {
testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc));
}

testcase_cleanup:
testcase_user_logout();
loc_rc = funcs->C_CloseAllSessions(slot_id);
if (loc_rc != CKR_OK) {
testcase_error("C_CloseAllSessions, rc=%s", p11_get_ckr(loc_rc));
}

return rc;
}

CK_RV rsa_funcs(void)
{
unsigned int i;
Expand Down Expand Up @@ -2032,6 +2190,13 @@ CK_RV rsa_funcs(void)
break;
}

// Implicit rejection tests
for (i = 0; i < NUM_OF_IMPLICIT_REJECTION_TESTSUITES; i++) {
rv = do_RSAImplicitRejection(&rsa_implicit_rejection_test_suites[i]);
if (rv != CKR_OK && (!no_stop))
break;
}

return rv;
}

Expand Down
11 changes: 10 additions & 1 deletion usr/lib/common/h_extern.h
Expand Up @@ -731,7 +731,8 @@ CK_RV rsa_format_block(STDLL_TokData_t *tokdata,
CK_RV rsa_parse_block(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
CK_ULONG *out_data_len, CK_ULONG type);
CK_ULONG *out_data_len, CK_ULONG type,
CK_BYTE *kdk, CK_ULONG kdklen);

CK_RV get_mgf_mech(CK_RSA_PKCS_MGF_TYPE mgf, CK_MECHANISM_TYPE *mech);

Expand Down Expand Up @@ -3182,6 +3183,14 @@ CK_RV openssl_specific_hmac_update(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data,
CK_RV openssl_specific_hmac_final(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *signature,
CK_ULONG *sig_len, CK_BBOOL sign);

CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
const CK_BYTE *in, CK_ULONG inlen,
CK_BYTE *kdk, CK_ULONG kdklen);
CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen,
const char *label, CK_ULONG labellen,
const CK_BYTE *kdk, CK_ULONG kdklen,
uint16_t bitlen);

#include "tok_spec_struct.h"
extern token_spec_t token_specific;

Expand Down