186922832SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause 286922832SVesa Jääskeläinen /* 386922832SVesa Jääskeläinen * Copyright (c) 2018-2021, Linaro Limited 486922832SVesa Jääskeläinen */ 586922832SVesa Jääskeläinen 686922832SVesa Jääskeläinen #include <assert.h> 786922832SVesa Jääskeläinen #include <pkcs11_ta.h> 886922832SVesa Jääskeläinen #include <tee_api_defines.h> 986922832SVesa Jääskeläinen #include <tee_internal_api.h> 1086922832SVesa Jääskeläinen #include <tee_internal_api_extensions.h> 1186922832SVesa Jääskeläinen 1286922832SVesa Jääskeläinen #include "attributes.h" 130442c956SVesa Jääskeläinen #include "object.h" 14*d9af50bcSVesa Jääskeläinen #include "pkcs11_token.h" 1586922832SVesa Jääskeläinen #include "processing.h" 1686922832SVesa Jääskeläinen 17*d9af50bcSVesa Jääskeläinen enum pkcs11_rc 18*d9af50bcSVesa Jääskeläinen pkcs2tee_proc_params_rsa_pss(struct active_processing *proc, 19*d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params) 20*d9af50bcSVesa Jääskeläinen { 21*d9af50bcSVesa Jääskeläinen struct serialargs args = { }; 22*d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 23*d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *ctx = NULL; 24*d9af50bcSVesa Jääskeläinen uint32_t hash = 0; 25*d9af50bcSVesa Jääskeläinen uint32_t mgf = 0; 26*d9af50bcSVesa Jääskeläinen uint32_t salt_len = 0; 27*d9af50bcSVesa Jääskeläinen 28*d9af50bcSVesa Jääskeläinen serialargs_init(&args, proc_params->data, proc_params->size); 29*d9af50bcSVesa Jääskeläinen 30*d9af50bcSVesa Jääskeläinen rc = serialargs_get_u32(&args, &hash); 31*d9af50bcSVesa Jääskeläinen if (rc) 32*d9af50bcSVesa Jääskeläinen return rc; 33*d9af50bcSVesa Jääskeläinen 34*d9af50bcSVesa Jääskeläinen rc = serialargs_get_u32(&args, &mgf); 35*d9af50bcSVesa Jääskeläinen if (rc) 36*d9af50bcSVesa Jääskeläinen return rc; 37*d9af50bcSVesa Jääskeläinen 38*d9af50bcSVesa Jääskeläinen rc = serialargs_get_u32(&args, &salt_len); 39*d9af50bcSVesa Jääskeläinen if (rc) 40*d9af50bcSVesa Jääskeläinen return rc; 41*d9af50bcSVesa Jääskeläinen 42*d9af50bcSVesa Jääskeläinen if (serialargs_remaining_bytes(&args)) 43*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 44*d9af50bcSVesa Jääskeläinen 45*d9af50bcSVesa Jääskeläinen proc->extra_ctx = TEE_Malloc(sizeof(struct rsa_pss_processing_ctx), 46*d9af50bcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 47*d9af50bcSVesa Jääskeläinen if (!proc->extra_ctx) 48*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 49*d9af50bcSVesa Jääskeläinen 50*d9af50bcSVesa Jääskeläinen ctx = proc->extra_ctx; 51*d9af50bcSVesa Jääskeläinen 52*d9af50bcSVesa Jääskeläinen ctx->hash_alg = hash; 53*d9af50bcSVesa Jääskeläinen ctx->mgf_type = mgf; 54*d9af50bcSVesa Jääskeläinen ctx->salt_len = salt_len; 55*d9af50bcSVesa Jääskeläinen 56*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 57*d9af50bcSVesa Jääskeläinen } 58*d9af50bcSVesa Jääskeläinen 59*d9af50bcSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_validate_rsa_pss(struct active_processing *proc, 60*d9af50bcSVesa Jääskeläinen struct pkcs11_object *obj) 61*d9af50bcSVesa Jääskeläinen { 62*d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; 63*d9af50bcSVesa Jääskeläinen size_t modulus_size = 0; 64*d9af50bcSVesa Jääskeläinen size_t hash_size = 0; 65*d9af50bcSVesa Jääskeläinen uint32_t k = 0; 66*d9af50bcSVesa Jääskeläinen 67*d9af50bcSVesa Jääskeläinen rsa_pss_ctx = proc->extra_ctx; 68*d9af50bcSVesa Jääskeläinen assert(rsa_pss_ctx); 69*d9af50bcSVesa Jääskeläinen 70*d9af50bcSVesa Jääskeläinen switch (rsa_pss_ctx->hash_alg) { 71*d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA_1: 72*d9af50bcSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA1); 73*d9af50bcSVesa Jääskeläinen break; 74*d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224: 75*d9af50bcSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA224); 76*d9af50bcSVesa Jääskeläinen break; 77*d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256: 78*d9af50bcSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA256); 79*d9af50bcSVesa Jääskeläinen break; 80*d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384: 81*d9af50bcSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA384); 82*d9af50bcSVesa Jääskeläinen break; 83*d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512: 84*d9af50bcSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA512); 85*d9af50bcSVesa Jääskeläinen break; 86*d9af50bcSVesa Jääskeläinen default: 87*d9af50bcSVesa Jääskeläinen assert(0); 88*d9af50bcSVesa Jääskeläinen break; 89*d9af50bcSVesa Jääskeläinen } 90*d9af50bcSVesa Jääskeläinen 91*d9af50bcSVesa Jääskeläinen modulus_size = get_object_key_bit_size(obj); 92*d9af50bcSVesa Jääskeläinen 93*d9af50bcSVesa Jääskeläinen /** 94*d9af50bcSVesa Jääskeläinen * The sLen field must be less than or equal to k*-2-hLen where 95*d9af50bcSVesa Jääskeläinen * hLen is the length in bytes of the hash value. k* is the 96*d9af50bcSVesa Jääskeläinen * length in bytes of the RSA modulus, except if the length in 97*d9af50bcSVesa Jääskeläinen * bits of the RSA modulus is one more than a multiple of 8, in 98*d9af50bcSVesa Jääskeläinen * which case k* is one less than the length in bytes of the 99*d9af50bcSVesa Jääskeläinen * RSA modulus. 100*d9af50bcSVesa Jääskeläinen */ 101*d9af50bcSVesa Jääskeläinen if ((modulus_size % 8) == 1) 102*d9af50bcSVesa Jääskeläinen k = modulus_size / 8; 103*d9af50bcSVesa Jääskeläinen else 104*d9af50bcSVesa Jääskeläinen k = ROUNDUP(modulus_size, 8) / 8; 105*d9af50bcSVesa Jääskeläinen 106*d9af50bcSVesa Jääskeläinen if (rsa_pss_ctx->salt_len > (k - 2 - hash_size)) 107*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_KEY_SIZE_RANGE; 108*d9af50bcSVesa Jääskeläinen 109*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 110*d9af50bcSVesa Jääskeläinen } 111*d9af50bcSVesa Jääskeläinen 112*d9af50bcSVesa Jääskeläinen /* 113*d9af50bcSVesa Jääskeläinen * Check or set TEE algorithm identifier upon PKCS11 mechanism parameters 114*d9af50bcSVesa Jääskeläinen * @tee_id: Input and/or output TEE algorithm identifier 115*d9af50bcSVesa Jääskeläinen * @proc_params: PKCS11 processing parameters 116*d9af50bcSVesa Jääskeläinen */ 117*d9af50bcSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_algo_rsa_pss(uint32_t *tee_id, 118*d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params) 119*d9af50bcSVesa Jääskeläinen { 120*d9af50bcSVesa Jääskeläinen struct serialargs args = { }; 121*d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 122*d9af50bcSVesa Jääskeläinen uint32_t hash = 0; 123*d9af50bcSVesa Jääskeläinen uint32_t mgf = 0; 124*d9af50bcSVesa Jääskeläinen uint32_t salt_len = 0; 125*d9af50bcSVesa Jääskeläinen 126*d9af50bcSVesa Jääskeläinen serialargs_init(&args, proc_params->data, proc_params->size); 127*d9af50bcSVesa Jääskeläinen 128*d9af50bcSVesa Jääskeläinen rc = serialargs_get_u32(&args, &hash); 129*d9af50bcSVesa Jääskeläinen if (rc) 130*d9af50bcSVesa Jääskeläinen return rc; 131*d9af50bcSVesa Jääskeläinen 132*d9af50bcSVesa Jääskeläinen rc = serialargs_get_u32(&args, &mgf); 133*d9af50bcSVesa Jääskeläinen if (rc) 134*d9af50bcSVesa Jääskeläinen return rc; 135*d9af50bcSVesa Jääskeläinen 136*d9af50bcSVesa Jääskeläinen rc = serialargs_get_u32(&args, &salt_len); 137*d9af50bcSVesa Jääskeläinen if (rc) 138*d9af50bcSVesa Jääskeläinen return rc; 139*d9af50bcSVesa Jääskeläinen 140*d9af50bcSVesa Jääskeläinen if (serialargs_remaining_bytes(&args)) 141*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 142*d9af50bcSVesa Jääskeläinen 143*d9af50bcSVesa Jääskeläinen if (proc_params->id == PKCS11_CKM_RSA_PKCS_PSS) { 144*d9af50bcSVesa Jääskeläinen if (hash == PKCS11_CKM_SHA_1 && mgf == PKCS11_CKG_MGF1_SHA1) { 145*d9af50bcSVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1; 146*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 147*d9af50bcSVesa Jääskeläinen } 148*d9af50bcSVesa Jääskeläinen if (hash == PKCS11_CKM_SHA224 && 149*d9af50bcSVesa Jääskeläinen mgf == PKCS11_CKG_MGF1_SHA224) { 150*d9af50bcSVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224; 151*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 152*d9af50bcSVesa Jääskeläinen } 153*d9af50bcSVesa Jääskeläinen if (hash == PKCS11_CKM_SHA256 && 154*d9af50bcSVesa Jääskeläinen mgf == PKCS11_CKG_MGF1_SHA256) { 155*d9af50bcSVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256; 156*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 157*d9af50bcSVesa Jääskeläinen } 158*d9af50bcSVesa Jääskeläinen if (hash == PKCS11_CKM_SHA384 && 159*d9af50bcSVesa Jääskeläinen mgf == PKCS11_CKG_MGF1_SHA384) { 160*d9af50bcSVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384; 161*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 162*d9af50bcSVesa Jääskeläinen } 163*d9af50bcSVesa Jääskeläinen if (hash == PKCS11_CKM_SHA512 && 164*d9af50bcSVesa Jääskeläinen mgf == PKCS11_CKG_MGF1_SHA512) { 165*d9af50bcSVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512; 166*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 167*d9af50bcSVesa Jääskeläinen } 168*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_PARAM_INVALID; 169*d9af50bcSVesa Jääskeläinen } 170*d9af50bcSVesa Jääskeläinen 171*d9af50bcSVesa Jääskeläinen switch (*tee_id) { 172*d9af50bcSVesa Jääskeläinen case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 173*d9af50bcSVesa Jääskeläinen if (hash != PKCS11_CKM_SHA_1 || mgf != PKCS11_CKG_MGF1_SHA1) 174*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_PARAM_INVALID; 175*d9af50bcSVesa Jääskeläinen break; 176*d9af50bcSVesa Jääskeläinen case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 177*d9af50bcSVesa Jääskeläinen if (hash != PKCS11_CKM_SHA224 || mgf != PKCS11_CKG_MGF1_SHA224) 178*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_PARAM_INVALID; 179*d9af50bcSVesa Jääskeläinen break; 180*d9af50bcSVesa Jääskeläinen case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 181*d9af50bcSVesa Jääskeläinen if (hash != PKCS11_CKM_SHA256 || mgf != PKCS11_CKG_MGF1_SHA256) 182*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_PARAM_INVALID; 183*d9af50bcSVesa Jääskeläinen break; 184*d9af50bcSVesa Jääskeläinen case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 185*d9af50bcSVesa Jääskeläinen if (hash != PKCS11_CKM_SHA384 || mgf != PKCS11_CKG_MGF1_SHA384) 186*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_PARAM_INVALID; 187*d9af50bcSVesa Jääskeläinen break; 188*d9af50bcSVesa Jääskeläinen case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 189*d9af50bcSVesa Jääskeläinen if (hash != PKCS11_CKM_SHA512 || mgf != PKCS11_CKG_MGF1_SHA512) 190*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_PARAM_INVALID; 191*d9af50bcSVesa Jääskeläinen break; 192*d9af50bcSVesa Jääskeläinen default: 193*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 194*d9af50bcSVesa Jääskeläinen } 195*d9af50bcSVesa Jääskeläinen 196*d9af50bcSVesa Jääskeläinen return PKCS11_CKR_OK; 197*d9af50bcSVesa Jääskeläinen } 198*d9af50bcSVesa Jääskeläinen 1990442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs, 2000442c956SVesa Jääskeläinen size_t *tee_count, 2010442c956SVesa Jääskeläinen struct pkcs11_object *obj) 2020442c956SVesa Jääskeläinen { 2030442c956SVesa Jääskeläinen TEE_Attribute *attrs = NULL; 2040442c956SVesa Jääskeläinen size_t count = 0; 2050442c956SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 2060442c956SVesa Jääskeläinen void *a_ptr = NULL; 2070442c956SVesa Jääskeläinen 2080442c956SVesa Jääskeläinen assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA); 2090442c956SVesa Jääskeläinen 2100442c956SVesa Jääskeläinen switch (get_class(obj->attributes)) { 2110442c956SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 2120442c956SVesa Jääskeläinen attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), 2130442c956SVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 2140442c956SVesa Jääskeläinen if (!attrs) 2150442c956SVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 2160442c956SVesa Jääskeläinen 2170442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS, 2180442c956SVesa Jääskeläinen obj, PKCS11_CKA_MODULUS)) 2190442c956SVesa Jääskeläinen count++; 2200442c956SVesa Jääskeläinen 2210442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], 2220442c956SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT, obj, 2230442c956SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT)) 2240442c956SVesa Jääskeläinen count++; 2250442c956SVesa Jääskeläinen 2260442c956SVesa Jääskeläinen if (count == 2) 2270442c956SVesa Jääskeläinen rc = PKCS11_CKR_OK; 2280442c956SVesa Jääskeläinen 2290442c956SVesa Jääskeläinen break; 2300442c956SVesa Jääskeläinen 2310442c956SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 2320442c956SVesa Jääskeläinen attrs = TEE_Malloc(8 * sizeof(TEE_Attribute), 2330442c956SVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 2340442c956SVesa Jääskeläinen if (!attrs) 2350442c956SVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 2360442c956SVesa Jääskeläinen 2370442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS, 2380442c956SVesa Jääskeläinen obj, PKCS11_CKA_MODULUS)) 2390442c956SVesa Jääskeläinen count++; 2400442c956SVesa Jääskeläinen 2410442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], 2420442c956SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT, obj, 2430442c956SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT)) 2440442c956SVesa Jääskeläinen count++; 2450442c956SVesa Jääskeläinen 2460442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], 2470442c956SVesa Jääskeläinen TEE_ATTR_RSA_PRIVATE_EXPONENT, obj, 2480442c956SVesa Jääskeläinen PKCS11_CKA_PRIVATE_EXPONENT)) 2490442c956SVesa Jääskeläinen count++; 2500442c956SVesa Jääskeläinen 2510442c956SVesa Jääskeläinen if (count != 3) 2520442c956SVesa Jääskeläinen break; 2530442c956SVesa Jääskeläinen 2540442c956SVesa Jääskeläinen /* If pre-computed values are present load those */ 2550442c956SVesa Jääskeläinen rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1, 2560442c956SVesa Jääskeläinen &a_ptr, NULL); 2570442c956SVesa Jääskeläinen if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 2580442c956SVesa Jääskeläinen break; 2590442c956SVesa Jääskeläinen if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) { 2600442c956SVesa Jääskeläinen rc = PKCS11_CKR_OK; 2610442c956SVesa Jääskeläinen break; 2620442c956SVesa Jääskeläinen } 2630442c956SVesa Jääskeläinen 2640442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj, 2650442c956SVesa Jääskeläinen PKCS11_CKA_PRIME_1)) 2660442c956SVesa Jääskeläinen count++; 2670442c956SVesa Jääskeläinen 2680442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj, 2690442c956SVesa Jääskeläinen PKCS11_CKA_PRIME_2)) 2700442c956SVesa Jääskeläinen count++; 2710442c956SVesa Jääskeläinen 2720442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1, 2730442c956SVesa Jääskeläinen obj, PKCS11_CKA_EXPONENT_1)) 2740442c956SVesa Jääskeläinen count++; 2750442c956SVesa Jääskeläinen 2760442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2, 2770442c956SVesa Jääskeläinen obj, PKCS11_CKA_EXPONENT_2)) 2780442c956SVesa Jääskeläinen count++; 2790442c956SVesa Jääskeläinen 2800442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT, 2810442c956SVesa Jääskeläinen obj, PKCS11_CKA_COEFFICIENT)) 2820442c956SVesa Jääskeläinen count++; 2830442c956SVesa Jääskeläinen 2840442c956SVesa Jääskeläinen if (count == 8) 2850442c956SVesa Jääskeläinen rc = PKCS11_CKR_OK; 2860442c956SVesa Jääskeläinen 2870442c956SVesa Jääskeläinen break; 2880442c956SVesa Jääskeläinen 2890442c956SVesa Jääskeläinen default: 2900442c956SVesa Jääskeläinen assert(0); 2910442c956SVesa Jääskeläinen break; 2920442c956SVesa Jääskeläinen } 2930442c956SVesa Jääskeläinen 2940442c956SVesa Jääskeläinen if (rc == PKCS11_CKR_OK) { 2950442c956SVesa Jääskeläinen *tee_attrs = attrs; 2960442c956SVesa Jääskeläinen *tee_count = count; 2970442c956SVesa Jääskeläinen } else { 2980442c956SVesa Jääskeläinen TEE_Free(attrs); 2990442c956SVesa Jääskeläinen } 3000442c956SVesa Jääskeläinen 3010442c956SVesa Jääskeläinen return rc; 3020442c956SVesa Jääskeläinen } 3030442c956SVesa Jääskeläinen 30486922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head, 30586922832SVesa Jääskeläinen struct obj_attrs **priv_head, 30686922832SVesa Jääskeläinen TEE_ObjectHandle tee_obj) 30786922832SVesa Jääskeläinen { 30886922832SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 30986922832SVesa Jääskeläinen void *a_ptr = NULL; 31086922832SVesa Jääskeläinen 31186922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj, 31286922832SVesa Jääskeläinen TEE_ATTR_RSA_MODULUS); 31386922832SVesa Jääskeläinen if (rc) 31486922832SVesa Jääskeläinen goto out; 31586922832SVesa Jääskeläinen 31686922832SVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr, 31786922832SVesa Jääskeläinen NULL); 31886922832SVesa Jääskeläinen if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 31986922832SVesa Jääskeläinen goto out; 32086922832SVesa Jääskeläinen 32186922832SVesa Jääskeläinen if (rc == PKCS11_CKR_OK && !a_ptr) { 32286922832SVesa Jääskeläinen rc = remove_empty_attribute(pub_head, 32386922832SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT); 32486922832SVesa Jääskeläinen if (rc) 32586922832SVesa Jääskeläinen goto out; 32686922832SVesa Jääskeläinen rc = PKCS11_RV_NOT_FOUND; 32786922832SVesa Jääskeläinen } 32886922832SVesa Jääskeläinen 32986922832SVesa Jääskeläinen if (rc == PKCS11_RV_NOT_FOUND) { 33086922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(pub_head, 33186922832SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 33286922832SVesa Jääskeläinen tee_obj, 33386922832SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT); 33486922832SVesa Jääskeläinen if (rc) 33586922832SVesa Jääskeläinen goto out; 33686922832SVesa Jääskeläinen } 33786922832SVesa Jääskeläinen 33886922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj, 33986922832SVesa Jääskeläinen TEE_ATTR_RSA_MODULUS); 34086922832SVesa Jääskeläinen if (rc) 34186922832SVesa Jääskeläinen goto out; 34286922832SVesa Jääskeläinen 34386922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT, 34486922832SVesa Jääskeläinen tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT); 34586922832SVesa Jääskeläinen if (rc) 34686922832SVesa Jääskeläinen goto out; 34786922832SVesa Jääskeläinen 34886922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT, 34986922832SVesa Jääskeläinen tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT); 35086922832SVesa Jääskeläinen if (rc) 35186922832SVesa Jääskeläinen goto out; 35286922832SVesa Jääskeläinen 35386922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj, 35486922832SVesa Jääskeläinen TEE_ATTR_RSA_PRIME1); 35586922832SVesa Jääskeläinen if (rc) 35686922832SVesa Jääskeläinen goto out; 35786922832SVesa Jääskeläinen 35886922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj, 35986922832SVesa Jääskeläinen TEE_ATTR_RSA_PRIME2); 36086922832SVesa Jääskeläinen if (rc) 36186922832SVesa Jääskeläinen goto out; 36286922832SVesa Jääskeläinen 36386922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj, 36486922832SVesa Jääskeläinen TEE_ATTR_RSA_EXPONENT1); 36586922832SVesa Jääskeläinen if (rc) 36686922832SVesa Jääskeläinen goto out; 36786922832SVesa Jääskeläinen 36886922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj, 36986922832SVesa Jääskeläinen TEE_ATTR_RSA_EXPONENT2); 37086922832SVesa Jääskeläinen if (rc) 37186922832SVesa Jääskeläinen goto out; 37286922832SVesa Jääskeläinen 37386922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj, 37486922832SVesa Jääskeläinen TEE_ATTR_RSA_COEFFICIENT); 37586922832SVesa Jääskeläinen out: 37686922832SVesa Jääskeläinen return rc; 37786922832SVesa Jääskeläinen } 37886922832SVesa Jääskeläinen 37986922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params, 38086922832SVesa Jääskeläinen struct obj_attrs **pub_head, 38186922832SVesa Jääskeläinen struct obj_attrs **priv_head) 38286922832SVesa Jääskeläinen { 38386922832SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 38486922832SVesa Jääskeläinen void *a_ptr = NULL; 38586922832SVesa Jääskeläinen uint32_t a_size = 0; 38686922832SVesa Jääskeläinen TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; 38786922832SVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 38886922832SVesa Jääskeläinen uint32_t modulus_bits = 0; 38986922832SVesa Jääskeläinen TEE_Attribute tee_attrs[1] = { }; 39086922832SVesa Jääskeläinen uint32_t tee_count = 0; 39186922832SVesa Jääskeläinen 39286922832SVesa Jääskeläinen if (!proc_params || !*pub_head || !*priv_head) 39386922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 39486922832SVesa Jääskeläinen 39586922832SVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr, 39686922832SVesa Jääskeläinen &a_size); 39786922832SVesa Jääskeläinen if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t)) 39886922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 39986922832SVesa Jääskeläinen 40086922832SVesa Jääskeläinen TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t)); 40186922832SVesa Jääskeläinen 40286922832SVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr, 40386922832SVesa Jääskeläinen &a_size); 40486922832SVesa Jääskeläinen if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 40586922832SVesa Jääskeläinen return rc; 40686922832SVesa Jääskeläinen 40786922832SVesa Jääskeläinen if (rc == PKCS11_CKR_OK && a_ptr) { 40886922832SVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_count], 40986922832SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT, 41086922832SVesa Jääskeläinen a_ptr, a_size); 41186922832SVesa Jääskeläinen tee_count++; 41286922832SVesa Jääskeläinen } 41386922832SVesa Jääskeläinen 41486922832SVesa Jääskeläinen if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) || 41586922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) || 41686922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) || 41786922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) || 41886922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) || 41986922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) || 42086922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) || 42186922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) { 42286922832SVesa Jääskeläinen EMSG("Unexpected attribute(s) found"); 42386922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 42486922832SVesa Jääskeläinen goto out; 42586922832SVesa Jääskeläinen } 42686922832SVesa Jääskeläinen 42786922832SVesa Jääskeläinen /* Create an RSA TEE key */ 42886922832SVesa Jääskeläinen res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits, 42986922832SVesa Jääskeläinen &tee_obj); 43086922832SVesa Jääskeläinen if (res) { 43186922832SVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res); 43286922832SVesa Jääskeläinen 43386922832SVesa Jääskeläinen rc = tee2pkcs_error(res); 43486922832SVesa Jääskeläinen goto out; 43586922832SVesa Jääskeläinen } 43686922832SVesa Jääskeläinen 43786922832SVesa Jääskeläinen res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); 43886922832SVesa Jääskeläinen if (res) { 43986922832SVesa Jääskeläinen DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res); 44086922832SVesa Jääskeläinen 44186922832SVesa Jääskeläinen rc = tee2pkcs_error(res); 44286922832SVesa Jääskeläinen goto out; 44386922832SVesa Jääskeläinen } 44486922832SVesa Jääskeläinen 44586922832SVesa Jääskeläinen res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count); 44686922832SVesa Jääskeläinen if (res) { 44786922832SVesa Jääskeläinen DMSG("TEE_GenerateKey failed %#"PRIx32, res); 44886922832SVesa Jääskeläinen 44986922832SVesa Jääskeläinen rc = tee2pkcs_error(res); 45086922832SVesa Jääskeläinen goto out; 45186922832SVesa Jääskeläinen } 45286922832SVesa Jääskeläinen 45386922832SVesa Jääskeläinen rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj); 45486922832SVesa Jääskeläinen 45586922832SVesa Jääskeläinen out: 45686922832SVesa Jääskeläinen if (tee_obj != TEE_HANDLE_NULL) 45786922832SVesa Jääskeläinen TEE_CloseObject(tee_obj); 45886922832SVesa Jääskeläinen 45986922832SVesa Jääskeläinen return rc; 46086922832SVesa Jääskeläinen } 4610442c956SVesa Jääskeläinen 4620442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op) 4630442c956SVesa Jääskeläinen { 4640442c956SVesa Jääskeläinen TEE_OperationInfo info = { }; 4650442c956SVesa Jääskeläinen 4660442c956SVesa Jääskeläinen TEE_GetOperationInfo(op, &info); 4670442c956SVesa Jääskeläinen 4680442c956SVesa Jääskeläinen return info.maxKeySize / 8; 4690442c956SVesa Jääskeläinen } 470