2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
25 #include <openssl/evp.h>
26 #include <openssl/obj_mac.h>
27 #include <openssl/ec.h>
28 #include <openssl/dsa.h>
29 #include <openssl/rsa.h>
30 #include <openssl/bio.h>
31 #include <openssl/rand.h>
32 #include <openssl/crypto.h>
33 #include <openssl/err.h>
34 #include <openssl/x509v3.h>
35 #include <openssl/obj_mac.h>
37 #include <ckm/ckm-error.h>
39 #include <dpl/log/log.h>
41 #include <generic-backend/exception.h>
42 #include <sw-backend/internals.h>
44 #define OPENSSL_SUCCESS 1 // DO NOTCHANGE THIS VALUE
45 #define OPENSSL_FAIL 0 // DO NOTCHANGE THIS VALUE
46 #define DEV_HW_RANDOM_FILE "/dev/hwrng"
47 #define DEV_URANDOM_FILE "/dev/urandom"
50 typedef std::unique_ptr<EVP_MD_CTX, std::function<void(EVP_MD_CTX*)>> EvpMdCtxUPtr;
51 typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX*)>> EvpPkeyCtxUPtr;
52 typedef std::unique_ptr<EVP_PKEY, std::function<void(EVP_PKEY*)>> EvpPkeyUPtr;
54 typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
55 typedef int(*I2D_CONV)(BIO*, EVP_PKEY*);
56 CKM::RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) {
57 BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
60 LogDebug("attempt to parse an empty key!");
61 ThrowMsg(CKM::Crypto::Exception::InternalError, "attempt to parse an empty key!");
64 if (NULL == bio.get()) {
65 LogError("Error in memory allocation! Function: BIO_new.");
66 ThrowMsg(CKM::Crypto::Exception::InternalError, "Error in memory allocation! Function: BIO_new.");
69 if (1 != fun(bio.get(), pkey)) {
70 LogError("Error in conversion EVP_PKEY to DER");
71 ThrowMsg(CKM::Crypto::Exception::InternalError, "Error in conversion EVP_PKEY to DER");
74 CKM::RawBuffer output(8196);
76 int size = BIO_read(bio.get(), output.data(), output.size());
79 LogError("Error in BIO_read: " << size);
80 ThrowMsg(CKM::Crypto::Exception::InternalError, "Error in BIO_read: " << size);
86 } // anonymous namespace
97 // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms
98 ERR_load_crypto_strings();
99 OpenSSL_add_all_algorithms();
101 // initialize entropy
102 std::ifstream ifile(DEV_HW_RANDOM_FILE);
103 if(ifile.is_open()) {
104 u_rand_ret= RAND_load_file(DEV_HW_RANDOM_FILE, 32);
106 if(u_rand_ret != 32 ){
107 LogError("Error in HW_RAND file load");
108 hw_rand_ret = RAND_load_file(DEV_URANDOM_FILE, 32);
110 if(hw_rand_ret != 32) {
111 LogError("Error in U_RAND_file_load");
112 ThrowMsg(Crypto::Exception::InternalError, "Error in U_RAND_file_load");
116 return CKM_CRYPTO_INIT_SUCCESS;
119 const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) {
120 const EVP_MD *md_algo=NULL;
122 case HashAlgorithm::NONE:
125 case HashAlgorithm::SHA1:
126 md_algo = EVP_sha1();
128 case HashAlgorithm::SHA256:
129 md_algo = EVP_sha256();
131 case HashAlgorithm::SHA384:
132 md_algo = EVP_sha384();
134 case HashAlgorithm::SHA512:
135 md_algo = EVP_sha512();
138 LogError("Error in hashAlgorithm value");
139 ThrowMsg(Crypto::Exception::InternalError, "Error in hashAlgorithm value");
144 int getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
145 int rsa_padding = -1;
147 case RSAPaddingAlgorithm::NONE:
148 rsa_padding = RSA_NO_PADDING;
150 case RSAPaddingAlgorithm::PKCS1:
151 rsa_padding = RSA_PKCS1_PADDING;
153 case RSAPaddingAlgorithm::X931:
154 rsa_padding = RSA_X931_PADDING;
157 LogError("Error in RSAPaddingAlgorithm value");
158 ThrowMsg(Crypto::Exception::InternalError, "Error in RSAPaddingAlgorithm value");
163 TokenPair createKeyPairRSA(CryptoBackend backendId, const int size)
167 // check the parameters of functions
168 if(size!=1024 && size!=2048 && size!=4096) {
169 LogError("Error in RSA input size");
170 ThrowMsg(Crypto::Exception::InputParam, "Error in RSA input size");
173 EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free);
175 LogError("Error in EVP_PKEY_CTX_new_id function !!");
176 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new_id function !!");
179 if(EVP_PKEY_keygen_init(ctx.get()) <= 0) {
180 LogError("Error in EVP_PKEY_keygen_init function !!");
181 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen_init function !!");
184 if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) {
185 LogError("Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
186 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
189 EVP_PKEY *pkeyTmp = NULL;
190 if(!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) {
191 LogError("Error in EVP_PKEY_keygen function !!");
192 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen function !!");
194 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
196 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
197 Token(backendId, DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
201 TokenPair createKeyPairDSA(CryptoBackend backendId, const int size)
206 // check the parameters of functions
207 if(size!=1024 && size!=2048 && size!=3072 && size!=4096) {
208 LogError("Error in DSA input size");
209 ThrowMsg(Exception::InputParam, "Error in DSA input size");
212 /* Create the context for generating the parameters */
213 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free);
215 LogError("Error in EVP_PKEY_CTX_new_id function");
216 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new_id function");
219 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
220 LogError("Error in EVP_PKEY_paramgen_init function");
221 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_paramgen_init function");
224 if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) {
225 LogError("Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
226 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
229 /* Generate parameters */
230 EVP_PKEY *pparamTmp = NULL;
231 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
232 LogError("Error in EVP_PKEY_paramgen function");
233 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_paramgen function");
235 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
237 // Start to generate key
238 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
240 LogError("Error in EVP_PKEY_CTX_new function");
241 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new function");
244 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
245 LogError("Error in EVP_PKEY_keygen_init function");
246 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen_init function");
249 /* Generate the key */
250 EVP_PKEY *pkeyTmp = NULL;
251 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
252 LogError("Error in EVP_PKEY_keygen function !!");
253 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen function !!");
255 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
257 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
258 Token(backendId, DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
261 TokenPair createKeyPairECDSA(CryptoBackend backendId, ElipticCurve type)
263 int ecCurve = NOT_DEFINED;
268 case ElipticCurve::prime192v1:
269 ecCurve = NID_X9_62_prime192v1;
271 case ElipticCurve::prime256v1:
272 ecCurve = NID_X9_62_prime256v1;
274 case ElipticCurve::secp384r1:
275 ecCurve = NID_secp384r1;
278 LogError("Error in EC type");
279 ThrowMsg(Exception::InputParam, "Error in EC type");
282 /* Create the context for generating the parameters */
283 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free);
285 LogError("Error in EVP_PKEY_CTX_new_id function");
286 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new_id function");
289 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) {
290 LogError("Error in EVP_PKEY_paramgen_init function");
291 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_paramgen_init function");
294 if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) {
295 LogError("Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
296 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
299 /* Generate parameters */
300 EVP_PKEY *pparamTmp = NULL;
301 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) {
302 LogError("Error in EVP_PKEY_paramgen function");
303 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_paramgen function");
305 pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
307 // Start to generate key
308 EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free);
310 LogError("Error in EVP_PKEY_CTX_new function");
311 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new function");
314 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) {
315 LogError("Error in EVP_PKEY_keygen_init function");
316 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen_init function");
319 /* Generate the key */
320 EVP_PKEY *pkeyTmp = NULL;
321 if(!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) {
322 LogError("Error in EVP_PKEY_keygen function !!");
323 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen function !!");
325 pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
327 return std::make_pair<Token, Token>(Token(backendId, DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())),
328 Token(backendId, DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())));
331 RawBuffer sign(EVP_PKEY *pkey,
332 const CryptoAlgorithm &alg,
333 const RawBuffer &message)
335 int rsa_padding = NOT_DEFINED;
336 const EVP_MD *md_algo = NULL;
338 HashAlgorithm hashTmp = HashAlgorithm::NONE;
339 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
340 md_algo = getMdAlgo(hashTmp);
342 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
343 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
344 rsa_padding = getRsaPadding(rsaPad);
347 // if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
348 // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
349 // (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
351 // LogError("Error in private key type");
352 // ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type");
355 // if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
356 // rsa_padding = getRsaPadding(padAlgo);
360 LogError("Error in EVP_PKEY_keygen function");
361 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_keygen function");
364 if(md_algo == NULL) {
365 return signMessage(pkey, message, rsa_padding);
368 return digestSignMessage(pkey,message, md_algo, rsa_padding);
371 RawBuffer signMessage(EVP_PKEY *privKey,
372 const RawBuffer &message,
373 const int rsa_padding)
375 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
378 LogError("Error in EVP_PKEY_CTX_new function");
379 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new function");
382 if(EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) {
383 LogError("Error in EVP_PKEY_sign_init function");
384 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_sign_init function");
387 /* Set padding algorithm */
388 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
389 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
390 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
391 ThrowMsg(Crypto::Exception::InternalError,
392 "Error in EVP_PKEY_CTX_set_rsa_padding function");
396 /* Finalize the Sign operation */
397 /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
398 * signature. Length is returned in slen */
400 if(EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())) {
401 LogError("Error in EVP_PKEY_sign function");
402 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_sign function");
405 /* Allocate memory for the signature based on size in slen */
408 if(EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
414 // Set value to return RawData
419 LogError("Error in EVP_PKEY_sign function. Input param error.");
420 ThrowMsg(Crypto::Exception::InputParam, "Error in EVP_PKEY_sign function. Input param error.");
423 RawBuffer digestSignMessage(EVP_PKEY *privKey,
424 const RawBuffer &message,
425 const EVP_MD *md_algo,
426 const int rsa_padding)
428 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
430 EVP_PKEY_CTX *pctx = NULL;
432 // Create the Message Digest Context
434 LogError("Error in EVP_MD_CTX_create function");
435 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_MD_CTX_create function");
438 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) {
439 LogError("Error in EVP_DigestSignInit function");
440 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_DigestSignInit function");
443 /* Set padding algorithm */
444 if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
445 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
446 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
447 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
451 /* Call update with the message */
452 if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())) {
453 LogError("Error in EVP_DigestSignUpdate function");
454 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_DigestSignUpdate function");
457 /* Finalize the DigestSign operation */
458 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
459 * signature. Length is returned in slen */
461 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) {
462 LogError("Error in EVP_DigestSignFinal function");
463 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_DigestSignFinal function");
466 /* Allocate memory for the signature based on size in slen */
469 /* Obtain the signature */
470 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) {
471 LogError("Error in EVP_DigestSignFinal function");
472 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_DigestSignFinal function");
475 // Set value to return RawData
480 int verify(EVP_PKEY *pkey,
481 const CryptoAlgorithm &alg,
482 const RawBuffer &message,
483 const RawBuffer &signature)
485 int rsa_padding = NOT_DEFINED;
486 const EVP_MD *md_algo = NULL;
488 HashAlgorithm hashTmp = HashAlgorithm::NONE;
489 alg.getParam(ParamName::SV_HASH_ALGO, hashTmp);
490 md_algo = getMdAlgo(hashTmp);
492 RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE;
493 alg.getParam(ParamName::SV_RSA_PADDING, rsaPad);
494 rsa_padding = getRsaPadding(rsaPad);
497 // if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
498 // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
499 // (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
501 // LogError("Error in private key type");
502 // ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type");
505 // if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
506 // rsa_padding = getRsaPadding(padAlgo);
509 // auto shrPKey = publicKey.getEvpShPtr();
511 LogError("Error in getEvpShPtr function");
512 ThrowMsg(Crypto::Exception::InternalError, "Error in getEvpShPtr function");
515 if (md_algo == NULL) {
516 return verifyMessage(pkey, message, signature, rsa_padding);
519 return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding);
522 int verifyMessage(EVP_PKEY *pubKey,
523 const RawBuffer &message,
524 const RawBuffer &signature,
525 const int rsa_padding)
527 EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
530 LogError("Error in EVP_PKEY_CTX_new function");
531 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_new function");
534 if(EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) {
535 LogError("Error in EVP_PKEY_verify_init function");
536 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_verify_init function");
539 /* Set padding algorithm */
540 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
541 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) {
542 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
543 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
547 if(EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) {
548 return CKM_API_SUCCESS;
551 LogError("EVP_PKEY_verify Failed");
552 return CKM_API_ERROR_VERIFICATION_FAILED;
555 int digestVerifyMessage(EVP_PKEY *pubKey,
556 const RawBuffer &message,
557 const RawBuffer &signature,
558 const EVP_MD *md_algo,
559 const int rsa_padding)
561 EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
562 EVP_PKEY_CTX *pctx = NULL;
564 /* Create the Message Digest Context */
566 LogError("Error in EVP_MD_CTX_create function");
567 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_MD_CTX_create function");
570 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) {
571 LogError("Error in EVP_DigestVerifyInit function");
572 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_DigestVerifyInit function");
575 if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
576 if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
577 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
578 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
582 if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()) ) {
583 LogError("Error in EVP_DigestVerifyUpdate function");
584 ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_DigestVerifyUpdate function");
587 if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size()) ) {
588 return CKM_API_SUCCESS;
591 LogError("EVP_PKEY_verify Failed");
592 return CKM_API_ERROR_VERIFICATION_FAILED;
595 } // namespace Internals
597 } // namespace Crypto