Skip to content

Commit

Permalink
ta: pkcs11: Add support for RSA PSS signing & verification
Browse files Browse the repository at this point in the history
Add support for performing RSA PSS signing & verification operations for:

- PKCS #1 RSA PSS with supplied hash value
- Multi stage SHA-1
- Multi stage SHA-224
- Multi stage SHA-256
- Multi stage SHA-384
- Multi stage SHA-512

Specified in:
PKCS #11 Cryptographic Token Interface Current Mechanisms Specification
Version 2.40 Plus Errata 01
2.1.10 PKCS #1 RSA PSS

Signed-off-by: Vesa Jääskeläinen <vesa.jaaskelainen@vaisala.com>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
  • Loading branch information
vesajaaskelainen authored and jforissier committed Aug 9, 2021
1 parent 0442c95 commit d9af50b
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 4 deletions.
30 changes: 30 additions & 0 deletions ta/pkcs11/include/pkcs11_ta.h
Original file line number Diff line number Diff line change
Expand Up @@ -1191,10 +1191,16 @@ enum pkcs11_mechanism_id {
PKCS11_CKM_RSA_PKCS = 0x00001,
PKCS11_CKM_MD5_RSA_PKCS = 0x00005,
PKCS11_CKM_SHA1_RSA_PKCS = 0x00006,
PKCS11_CKM_RSA_PKCS_PSS = 0x0000d,
PKCS11_CKM_SHA1_RSA_PKCS_PSS = 0x0000e,
PKCS11_CKM_SHA256_RSA_PKCS = 0x00040,
PKCS11_CKM_SHA384_RSA_PKCS = 0x00041,
PKCS11_CKM_SHA512_RSA_PKCS = 0x00042,
PKCS11_CKM_SHA256_RSA_PKCS_PSS = 0x00043,
PKCS11_CKM_SHA384_RSA_PKCS_PSS = 0x00044,
PKCS11_CKM_SHA512_RSA_PKCS_PSS = 0x00045,
PKCS11_CKM_SHA224_RSA_PKCS = 0x00046,
PKCS11_CKM_SHA224_RSA_PKCS_PSS = 0x00047,
PKCS11_CKM_MD5 = 0x00210,
PKCS11_CKM_MD5_HMAC = 0x00211,
PKCS11_CKM_SHA_1 = 0x00220,
Expand Down Expand Up @@ -1230,4 +1236,28 @@ enum pkcs11_mechanism_id {
PKCS11_PROCESSING_IMPORT = 0x80000000,
PKCS11_CKM_UNDEFINED_ID = PKCS11_UNDEFINED_ID,
};

/*
* PKCS11_CKD_<x> reflects CryptoKi client API key diff function IDs CKD_<x>.
*/
enum pkcs11_keydiff_id {
PKCS11_CKD_NULL = 0x0001,
/* Vendor extension: reserved for undefined ID (~0U) */
PKCS11_CKD_UNDEFINED_ID = PKCS11_UNDEFINED_ID,
};

/*
* Valid values MG function identifiers
* PKCS11_CKG_<x> reflects CryptoKi client API MG function IDs CKG_<x>.
*/
enum pkcs11_mgf_id {
PKCS11_CKG_MGF1_SHA1 = 0x0001,
PKCS11_CKG_MGF1_SHA224 = 0x0005,
PKCS11_CKG_MGF1_SHA256 = 0x0002,
PKCS11_CKG_MGF1_SHA384 = 0x0003,
PKCS11_CKG_MGF1_SHA512 = 0x0004,
/* Vendor extension: reserved for undefined ID (~0U) */
PKCS11_CKG_UNDEFINED_ID = PKCS11_UNDEFINED_ID,
};

#endif /*PKCS11_TA_H*/
6 changes: 6 additions & 0 deletions ta/pkcs11/src/pkcs11_attributes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,12 @@ check_parent_attrs_against_processing(enum pkcs11_mechanism_id proc_id,
case PKCS11_CKM_SHA256_RSA_PKCS:
case PKCS11_CKM_SHA384_RSA_PKCS:
case PKCS11_CKM_SHA512_RSA_PKCS:
case PKCS11_CKM_RSA_PKCS_PSS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
if (key_type != PKCS11_CKK_RSA) {
EMSG("Invalid key %s for mechanism %s",
id2str_type(key_type, key_class),
Expand Down
24 changes: 24 additions & 0 deletions ta/pkcs11/src/processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,27 @@
#define PKCS11_TA_PROCESSING_H

#include <pkcs11_attributes.h>
#include <pkcs11_ta.h>
#include <tee_internal_api.h>

struct pkcs11_client;
struct pkcs11_session;
struct pkcs11_object;
struct active_processing;

/**
* RSA PSS processing context
*
* @hash_alg: Hash algorithm mechanism
* @mgf_type: Mask generator function
* @salt_len: Length of the salt in bytes
*/
struct rsa_pss_processing_ctx {
enum pkcs11_mechanism_id hash_alg;
enum pkcs11_mgf_id mgf_type;
uint32_t salt_len;
};

/*
* Entry points from PKCS11 TA invocation commands
*/
Expand Down Expand Up @@ -142,6 +156,16 @@ enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
size_t *tee_count,
struct pkcs11_object *obj);

enum pkcs11_rc
pkcs2tee_proc_params_rsa_pss(struct active_processing *proc,
struct pkcs11_attribute_head *proc_params);

enum pkcs11_rc pkcs2tee_validate_rsa_pss(struct active_processing *proc,
struct pkcs11_object *obj);

enum pkcs11_rc pkcs2tee_algo_rsa_pss(uint32_t *tee_id,
struct pkcs11_attribute_head *params);

enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
struct obj_attrs **pub_head,
struct obj_attrs **priv_head);
Expand Down
103 changes: 99 additions & 4 deletions ta/pkcs11/src/processing_asymm.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ bool processing_is_tee_asymm(uint32_t proc_id)
switch (proc_id) {
/* RSA flavors */
case PKCS11_CKM_RSA_PKCS:
case PKCS11_CKM_RSA_PKCS_PSS:
case PKCS11_CKM_MD5_RSA_PKCS:
case PKCS11_CKM_SHA1_RSA_PKCS:
case PKCS11_CKM_SHA224_RSA_PKCS:
case PKCS11_CKM_SHA256_RSA_PKCS:
case PKCS11_CKM_SHA384_RSA_PKCS:
case PKCS11_CKM_SHA512_RSA_PKCS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
/* EC flavors */
case PKCS11_CKM_ECDSA:
case PKCS11_CKM_ECDSA_SHA1:
Expand All @@ -52,6 +58,7 @@ pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id,
} pkcs2tee_algo[] = {
/* RSA flavors */
{ PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 },
{ PKCS11_CKM_RSA_PKCS_PSS, 1, 0 },
{ PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5,
TEE_ALG_MD5 },
{ PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1,
Expand All @@ -64,6 +71,16 @@ pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id,
TEE_ALG_SHA384 },
{ PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512,
TEE_ALG_SHA512 },
{ PKCS11_CKM_SHA1_RSA_PKCS_PSS,
TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 },
{ PKCS11_CKM_SHA224_RSA_PKCS_PSS,
TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 },
{ PKCS11_CKM_SHA256_RSA_PKCS_PSS,
TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 },
{ PKCS11_CKM_SHA384_RSA_PKCS_PSS,
TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 },
{ PKCS11_CKM_SHA512_RSA_PKCS_PSS,
TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 },
/* EC flavors (Must find key size from the object) */
{ PKCS11_CKM_ECDSA, 1, 0 },
{ PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 },
Expand All @@ -87,6 +104,14 @@ pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id,
return PKCS11_RV_NOT_IMPLEMENTED;

switch (proc_params->id) {
case PKCS11_CKM_RSA_PKCS_PSS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params);
break;
case PKCS11_CKM_ECDSA:
case PKCS11_CKM_ECDSA_SHA1:
case PKCS11_CKM_ECDSA_SHA224:
Expand Down Expand Up @@ -313,10 +338,31 @@ static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
}

static enum pkcs11_rc
init_tee_operation(struct pkcs11_session *session __unused,
struct pkcs11_attribute_head *proc_params __unused)
init_tee_operation(struct pkcs11_session *session,
struct pkcs11_attribute_head *proc_params,
struct pkcs11_object *obj)
{
return PKCS11_CKR_OK;
enum pkcs11_rc rc = PKCS11_CKR_OK;
struct active_processing *proc = session->processing;

switch (proc_params->id) {
case PKCS11_CKM_RSA_PKCS_PSS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params);
if (rc)
break;

rc = pkcs2tee_validate_rsa_pss(proc, obj);
break;
default:
break;
}

return rc;
}

enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session,
Expand All @@ -336,7 +382,7 @@ enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session,
if (rc)
return rc;

return init_tee_operation(session, proc_params);
return init_tee_operation(session, proc_params, obj);
}

/*
Expand Down Expand Up @@ -367,6 +413,7 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
size_t tee_attrs_count = 0;
bool output_data = false;
struct active_processing *proc = session->processing;
struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL;
size_t sz = 0;

if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
Expand Down Expand Up @@ -399,6 +446,32 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
return PKCS11_CKR_GENERAL_ERROR;
}

/* TEE attribute(s) required by the operation */
switch (proc->mecha_type) {
case PKCS11_CKM_RSA_PKCS_PSS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
tee_attrs = TEE_Malloc(sizeof(TEE_Attribute),
TEE_USER_MEM_HINT_NO_FILL_ZERO);
if (!tee_attrs) {
rc = PKCS11_CKR_DEVICE_MEMORY;
goto out;
}

rsa_pss_ctx = proc->extra_ctx;

TEE_InitValueAttribute(&tee_attrs[tee_attrs_count],
TEE_ATTR_RSA_PSS_SALT_LENGTH,
rsa_pss_ctx->salt_len, 0);
tee_attrs_count++;
break;
default:
break;
}

/*
* Handle multi stage update step for mechas needing hash
* calculation
Expand All @@ -416,6 +489,11 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
case PKCS11_CKM_SHA256_RSA_PKCS:
case PKCS11_CKM_SHA384_RSA_PKCS:
case PKCS11_CKM_SHA512_RSA_PKCS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);

TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf,
Expand Down Expand Up @@ -449,6 +527,11 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
case PKCS11_CKM_SHA256_RSA_PKCS:
case PKCS11_CKM_SHA384_RSA_PKCS:
case PKCS11_CKM_SHA512_RSA_PKCS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);

hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo);
Expand Down Expand Up @@ -520,6 +603,12 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
case PKCS11_CKM_SHA256_RSA_PKCS:
case PKCS11_CKM_SHA384_RSA_PKCS:
case PKCS11_CKM_SHA512_RSA_PKCS:
case PKCS11_CKM_RSA_PKCS_PSS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
/* Get key size in bytes */
sz = rsa_get_input_max_byte_size(proc->tee_op_handle);
if (!sz) {
Expand All @@ -540,6 +629,7 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
switch (proc->mecha_type) {
case PKCS11_CKM_ECDSA:
case PKCS11_CKM_RSA_PKCS:
case PKCS11_CKM_RSA_PKCS_PSS:
/* For operations using provided input data */
switch (function) {
case PKCS11_FUNCTION_ENCRYPT:
Expand Down Expand Up @@ -595,6 +685,11 @@ enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
case PKCS11_CKM_SHA256_RSA_PKCS:
case PKCS11_CKM_SHA384_RSA_PKCS:
case PKCS11_CKM_SHA512_RSA_PKCS:
case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
/* For operations having hash operation use calculated hash */
switch (function) {
case PKCS11_FUNCTION_SIGN:
Expand Down
Loading

0 comments on commit d9af50b

Please sign in to comment.