components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/hw_pk11.c
changeset 1597 392a401c6d27
parent 1596 59869c4257d0
equal deleted inserted replaced
1596:59869c4257d0 1597:392a401c6d27
   308 static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
   308 static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
   309 static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
   309 static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
   310 static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
   310 static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
   311 
   311 
   312 static int pk11_choose_slots(int *any_slot_found);
   312 static int pk11_choose_slots(int *any_slot_found);
       
   313 static void pk11_choose_rand_slot(CK_TOKEN_INFO token_info,
       
   314     CK_SLOT_ID current_slot);
       
   315 static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info,
       
   316     CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv,
       
   317     int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar);
       
   318 static void pk11_choose_cipher_digest(int *local_cipher_nids,
       
   319     int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist,
       
   320     CK_SLOT_ID current_slot);
   313 static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
   321 static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
   314     CK_SLOT_ID current_slot, int *current_slot_n_cipher,
   322     CK_SLOT_ID current_slot, int *current_slot_n_cipher,
   315     int *local_cipher_nids);
   323     int *local_cipher_nids);
   316 static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
   324 static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
   317     CK_SLOT_ID current_slot, int *current_slot_n_digest,
   325     CK_SLOT_ID current_slot, int *current_slot_n_digest,
  3020 	CK_MECHANISM_INFO mech_info;
  3028 	CK_MECHANISM_INFO mech_info;
  3021 	CK_TOKEN_INFO token_info;
  3029 	CK_TOKEN_INFO token_info;
  3022 	int i;
  3030 	int i;
  3023 	CK_RV rv;
  3031 	CK_RV rv;
  3024 	CK_SLOT_ID best_pubkey_slot_sofar;
  3032 	CK_SLOT_ID best_pubkey_slot_sofar;
  3025 #ifdef DEBUG_SLOT_SELECTION
       
  3026 	CK_SLOT_ID best_cd_slot_sofar;
       
  3027 #endif
       
  3028 	int slot_n_cipher = -1;
       
  3029 	int slot_n_digest = -1;
       
  3030 	CK_SLOT_ID current_slot = 0;
  3033 	CK_SLOT_ID current_slot = 0;
  3031 	int current_slot_n_cipher = 0;
       
  3032 	int current_slot_n_digest = 0;
       
  3033 	int best_number_of_mechs = 0;
  3034 	int best_number_of_mechs = 0;
  3034 	int current_number_of_mechs = 0;
       
  3035 	int local_cipher_nids[PK11_CIPHER_MAX];
  3035 	int local_cipher_nids[PK11_CIPHER_MAX];
  3036 	int local_digest_nids[PK11_DIGEST_MAX];
  3036 	int local_digest_nids[PK11_DIGEST_MAX];
  3037 
  3037 
  3038 	/* let's initialize the output parameter */
  3038 	/* let's initialize the output parameter */
  3039 	if (any_slot_found != NULL)
  3039 	if (any_slot_found != NULL)
  3076 	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
  3076 	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
  3077 
  3077 
  3078 	pubkey_SLOTID = pSlotList[0];
  3078 	pubkey_SLOTID = pSlotList[0];
  3079 	for (i = 0; i < ulSlotCount; i++)
  3079 	for (i = 0; i < ulSlotCount; i++)
  3080 		{
  3080 		{
  3081 		CK_BBOOL slot_has_rsa = CK_FALSE;
       
  3082 		CK_BBOOL slot_has_dsa = CK_FALSE;
       
  3083 		CK_BBOOL slot_has_dh = CK_FALSE;
       
  3084 		current_slot = pSlotList[i];
  3081 		current_slot = pSlotList[i];
  3085 
  3082 
  3086 		DEBUG_SLOT_SEL("%s: == checking slot: %d ==\n", PK11_DBG,
  3083 		DEBUG_SLOT_SEL("%s: == checking slot: %d ==\n", PK11_DBG,
  3087 			current_slot);
  3084 			current_slot);
  3088 		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
  3085 		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
  3089 		if (rv != CKR_OK)
  3086 		if (rv != CKR_OK)
  3090 			continue;
  3087 			continue;
  3091 
  3088 
  3092 		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
  3089 		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
  3093 		    token_info.label);
  3090 		    token_info.label);
  3094 
  3091 		pk11_choose_rand_slot(token_info, current_slot);
  3095 		DEBUG_SLOT_SEL("%s: checking rand slots\n", PK11_DBG);
  3092 
  3096 
  3093 		pk11_choose_pubkey_slot(mech_info, token_info, current_slot,
  3097 		if (((token_info.flags & CKF_RNG) != 0) && !pk11_have_random)
  3094 			rv, best_number_of_mechs, best_pubkey_slot_sofar);
  3098 			{
  3095 
  3099 			DEBUG_SLOT_SEL(
  3096 		pk11_choose_cipher_digest(&local_cipher_nids,
  3100 			    "%s: this token has CKF_RNG flag\n", PK11_DBG);
  3097 			&local_digest_nids, pFuncList, current_slot);
  3101 			pk11_have_random = CK_TRUE;
       
  3102 			rand_SLOTID = current_slot;
       
  3103 			}
       
  3104 
       
  3105 		DEBUG_SLOT_SEL("%s: checking pubkey slots\n", PK11_DBG);
       
  3106 		current_number_of_mechs = 0;
       
  3107 
       
  3108 #ifndef OPENSSL_NO_RSA
       
  3109 		/*
       
  3110 		 * Check if this slot is capable of signing and
       
  3111 		 * verifying with CKM_RSA_PKCS.
       
  3112 		 */
       
  3113 		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
       
  3114 			&mech_info);
       
  3115 
       
  3116 		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3117 				(mech_info.flags & CKF_VERIFY)))
       
  3118 			{
       
  3119 			/*
       
  3120 			 * Check if this slot is capable of encryption,
       
  3121 			 * decryption, sign, and verify with CKM_RSA_X_509.
       
  3122 			 */
       
  3123 			rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3124 			    CKM_RSA_X_509, &mech_info);
       
  3125 
       
  3126 			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3127 			    (mech_info.flags & CKF_VERIFY) &&
       
  3128 			    (mech_info.flags & CKF_ENCRYPT) &&
       
  3129 			    (mech_info.flags & CKF_VERIFY_RECOVER) &&
       
  3130 			    (mech_info.flags & CKF_DECRYPT)))
       
  3131 				{
       
  3132 				slot_has_rsa = CK_TRUE;
       
  3133 				current_number_of_mechs++;
       
  3134 				}
       
  3135 			}
       
  3136 #endif	/* OPENSSL_NO_RSA */
       
  3137 
       
  3138 #ifndef OPENSSL_NO_DSA
       
  3139 		/*
       
  3140 		 * Check if this slot is capable of signing and
       
  3141 		 * verifying with CKM_DSA.
       
  3142 		 */
       
  3143 		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
       
  3144 			&mech_info);
       
  3145 		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3146 		    (mech_info.flags & CKF_VERIFY)))
       
  3147 			{
       
  3148 			slot_has_dsa = CK_TRUE;
       
  3149 			current_number_of_mechs++;
       
  3150 			}
       
  3151 
       
  3152 #endif	/* OPENSSL_NO_DSA */
       
  3153 
       
  3154 #ifndef OPENSSL_NO_DH
       
  3155 		/*
       
  3156 		 * Check if this slot is capable of DH key generataion and
       
  3157 		 * derivation.
       
  3158 		 */
       
  3159 		rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3160 		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
       
  3161 
       
  3162 		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
       
  3163 			{
       
  3164 			rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3165 				CKM_DH_PKCS_DERIVE, &mech_info);
       
  3166 			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
       
  3167 				{
       
  3168 				slot_has_dh = CK_TRUE;
       
  3169 				current_number_of_mechs++;
       
  3170 				}
       
  3171 			}
       
  3172 #endif	/* OPENSSL_NO_DH */
       
  3173 
       
  3174 		if (current_number_of_mechs > best_number_of_mechs)
       
  3175 			{
       
  3176 			best_pubkey_slot_sofar = current_slot;
       
  3177 			pk11_have_rsa = slot_has_rsa;
       
  3178 			pk11_have_dsa = slot_has_dsa;
       
  3179 			pk11_have_dh = slot_has_dh;
       
  3180 			best_number_of_mechs = current_number_of_mechs;
       
  3181 			/*
       
  3182 			 * Cache the flags for later use. We might need those if
       
  3183 			 * RSA keys by reference feature is used.
       
  3184 			 */
       
  3185 			pubkey_token_flags = token_info.flags;
       
  3186 			DEBUG_SLOT_SEL("%s: pubkey flags changed to "
       
  3187 			    "%lu.\n", PK11_DBG, pubkey_token_flags);
       
  3188 			}
       
  3189 
       
  3190 		DEBUG_SLOT_SEL("%s: checking cipher/digest\n", PK11_DBG);
       
  3191 
       
  3192 		current_slot_n_cipher = 0;
       
  3193 		current_slot_n_digest = 0;
       
  3194 		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
       
  3195 		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
       
  3196 
       
  3197 		pk11_find_symmetric_ciphers(pFuncList, current_slot,
       
  3198 		    &current_slot_n_cipher, local_cipher_nids);
       
  3199 
       
  3200 		pk11_find_digests(pFuncList, current_slot,
       
  3201 		    &current_slot_n_digest, local_digest_nids);
       
  3202 
       
  3203 		DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
       
  3204 			current_slot_n_cipher);
       
  3205 		DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
       
  3206 			current_slot_n_digest);
       
  3207 
       
  3208 		/*
       
  3209 		 * If the current slot supports more ciphers/digests than
       
  3210 		 * the previous best one we change the current best to this one,
       
  3211 		 * otherwise leave it where it is.
       
  3212 		 */
       
  3213 		if ((current_slot_n_cipher + current_slot_n_digest) >
       
  3214 		    (slot_n_cipher + slot_n_digest))
       
  3215 			{
       
  3216 			DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
       
  3217 				PK11_DBG, current_slot);
       
  3218 			SLOTID = current_slot;
       
  3219 #ifdef DEBUG_SLOT_SELECTION
       
  3220 			best_cd_slot_sofar = current_slot;
       
  3221 #endif
       
  3222 			cipher_count = slot_n_cipher = current_slot_n_cipher;
       
  3223 			digest_count = slot_n_digest = current_slot_n_digest;
       
  3224 			(void) memcpy(cipher_nids, local_cipher_nids,
       
  3225 			    sizeof (local_cipher_nids));
       
  3226 			(void) memcpy(digest_nids, local_digest_nids,
       
  3227 			    sizeof (local_digest_nids));
       
  3228 			}
       
  3229 
       
  3230 		DEBUG_SLOT_SEL("%s: best cipher/digest slot so far: %d\n",
       
  3231 			PK11_DBG, best_cd_slot_sofar);
       
  3232 		}
  3098 		}
  3233 
  3099 
  3234 	if (best_number_of_mechs == 0)
  3100 	if (best_number_of_mechs == 0)
  3235 		{
  3101 		{
  3236 		DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
  3102 		DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
  3259 #endif	/* SOLARIS_HW_SLOT_SELECTION */
  3125 #endif	/* SOLARIS_HW_SLOT_SELECTION */
  3260 
  3126 
  3261 	if (any_slot_found != NULL)
  3127 	if (any_slot_found != NULL)
  3262 		*any_slot_found = 1;
  3128 		*any_slot_found = 1;
  3263 	return (1);
  3129 	return (1);
       
  3130 	}
       
  3131 
       
  3132 static void pk11_choose_rand_slot(CK_TOKEN_INFO token_info,
       
  3133     CK_SLOT_ID current_slot)
       
  3134 	{
       
  3135 	DEBUG_SLOT_SEL("%s: checking rand slots\n", PK11_DBG);
       
  3136 
       
  3137 	if (((token_info.flags & CKF_RNG) != 0) && !pk11_have_random)
       
  3138 		{
       
  3139 		DEBUG_SLOT_SEL(
       
  3140 		    "%s: this token has CKF_RNG flag\n", PK11_DBG);
       
  3141 		pk11_have_random = CK_TRUE;
       
  3142 		rand_SLOTID = current_slot;
       
  3143 		}
       
  3144 	}
       
  3145 
       
  3146 static void pk11_choose_pubkey_slot(CK_MECHANISM_INFO mech_info,
       
  3147     CK_TOKEN_INFO token_info, CK_SLOT_ID current_slot, CK_RV rv,
       
  3148     int best_number_of_mechs, CK_SLOT_ID best_pubkey_slot_sofar)
       
  3149 	{
       
  3150 	CK_BBOOL slot_has_rsa = CK_FALSE;
       
  3151 	CK_BBOOL slot_has_dsa = CK_FALSE;
       
  3152 	CK_BBOOL slot_has_dh = CK_FALSE;
       
  3153 	int current_number_of_mechs = 0;
       
  3154 	DEBUG_SLOT_SEL("%s: checking pubkey slots\n", PK11_DBG);
       
  3155 
       
  3156 #ifndef OPENSSL_NO_RSA
       
  3157 	/*
       
  3158 	 * Check if this slot is capable of signing and
       
  3159 	 * verifying with CKM_RSA_PKCS.
       
  3160 	 */
       
  3161 	rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
       
  3162 		&mech_info);
       
  3163 
       
  3164 	if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3165 			(mech_info.flags & CKF_VERIFY)))
       
  3166 		{
       
  3167 		/*
       
  3168 		 * Check if this slot is capable of encryption,
       
  3169 		 * decryption, sign, and verify with CKM_RSA_X_509.
       
  3170 		 */
       
  3171 		rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3172 			CKM_RSA_X_509, &mech_info);
       
  3173 
       
  3174 		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3175 		    (mech_info.flags & CKF_VERIFY) &&
       
  3176 		    (mech_info.flags & CKF_ENCRYPT) &&
       
  3177 		    (mech_info.flags & CKF_VERIFY_RECOVER) &&
       
  3178 		    (mech_info.flags & CKF_DECRYPT)))
       
  3179 			{
       
  3180 			slot_has_rsa = CK_TRUE;
       
  3181 			current_number_of_mechs++;
       
  3182 			}
       
  3183 		}
       
  3184 #endif  /* OPENSSL_NO_RSA */
       
  3185 
       
  3186 #ifndef OPENSSL_NO_DSA
       
  3187 	/*
       
  3188 	 * Check if this slot is capable of signing and
       
  3189 	 * verifying with CKM_DSA.
       
  3190 	 */
       
  3191 	rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
       
  3192 		&mech_info);
       
  3193 	if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
       
  3194 	    (mech_info.flags & CKF_VERIFY)))
       
  3195 		{
       
  3196 		slot_has_dsa = CK_TRUE;
       
  3197 		current_number_of_mechs++;
       
  3198 		}
       
  3199 
       
  3200 #endif  /* OPENSSL_NO_DSA */
       
  3201 
       
  3202 #ifndef OPENSSL_NO_DH
       
  3203 	/*
       
  3204 	 * Check if this slot is capable of DH key generataion and
       
  3205 	 * derivation.
       
  3206 	 */
       
  3207 	rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3208 	    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
       
  3209 
       
  3210 	if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
       
  3211 		{
       
  3212 		rv = pFuncList->C_GetMechanismInfo(current_slot,
       
  3213 			CKM_DH_PKCS_DERIVE, &mech_info);
       
  3214 		if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
       
  3215 			{
       
  3216 			slot_has_dh = CK_TRUE;
       
  3217 			current_number_of_mechs++;
       
  3218 			}
       
  3219 		}
       
  3220 #endif  /* OPENSSL_NO_DH */
       
  3221 
       
  3222 	if (current_number_of_mechs > best_number_of_mechs)
       
  3223 		{
       
  3224 		best_pubkey_slot_sofar = current_slot;
       
  3225 		pk11_have_rsa = slot_has_rsa;
       
  3226 		pk11_have_dsa = slot_has_dsa;
       
  3227 		pk11_have_dh = slot_has_dh;
       
  3228 		best_number_of_mechs = current_number_of_mechs;
       
  3229 		/*
       
  3230 		 * Cache the flags for later use. We might need those if
       
  3231 		 * RSA keys by reference feature is used.
       
  3232 		 */
       
  3233 		pubkey_token_flags = token_info.flags;
       
  3234 		DEBUG_SLOT_SEL("%s: pubkey flags changed to "
       
  3235 		    "%lu.\n", PK11_DBG, pubkey_token_flags);
       
  3236 		}
       
  3237 	}
       
  3238 
       
  3239 static void pk11_choose_cipher_digest(int *local_cipher_nids,
       
  3240     int *local_digest_nids, CK_FUNCTION_LIST_PTR pflist,
       
  3241     CK_SLOT_ID current_slot)
       
  3242 	{
       
  3243 	int current_slot_n_cipher = 0;
       
  3244 	int current_slot_n_digest = 0;
       
  3245 
       
  3246 	DEBUG_SLOT_SEL("%s: checking cipher/digest\n", PK11_DBG);
       
  3247 
       
  3248 	(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
       
  3249 	(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
       
  3250 
       
  3251 	pk11_find_symmetric_ciphers(pFuncList, current_slot,
       
  3252 	    &current_slot_n_cipher, local_cipher_nids);
       
  3253 
       
  3254 	pk11_find_digests(pFuncList, current_slot,
       
  3255 	    &current_slot_n_digest, local_digest_nids);
       
  3256 
       
  3257 	DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
       
  3258 		current_slot_n_cipher);
       
  3259 	DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
       
  3260 		current_slot_n_digest);
       
  3261 
       
  3262 	/*
       
  3263 	 * If the current slot supports more ciphers/digests than
       
  3264 	 * the previous best one we change the current best to this one,
       
  3265 	 * otherwise leave it where it is.
       
  3266 	 */
       
  3267 	if ((current_slot_n_cipher + current_slot_n_digest) >
       
  3268 	    (cipher_count + digest_count))
       
  3269 		{
       
  3270 		DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
       
  3271 			PK11_DBG, current_slot);
       
  3272 		SLOTID = current_slot;
       
  3273 		cipher_count = current_slot_n_cipher;
       
  3274 		digest_count = current_slot_n_digest;
       
  3275 		(void) memcpy(cipher_nids, local_cipher_nids,
       
  3276 			sizeof (local_cipher_nids));
       
  3277 		(void) memcpy(digest_nids, local_digest_nids,
       
  3278 			sizeof (local_digest_nids));
       
  3279 		}
  3264 	}
  3280 	}
  3265 
  3281 
  3266 static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
  3282 static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
  3267     int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
  3283     int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
  3268     PK11_CIPHER *cipher)
  3284     PK11_CIPHER *cipher)