* otherwise a negative error value
* @retval #CKMC_ERROR_NONE Successful
* @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid
- * mandatory algorithm parameter, decrypted = NULL,
+ * mandatory algorithm parameter or RSA data too long, decrypted = NULL,
* ppencrypted = NULL)
* @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in)
* @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason
* otherwise a negative error value
* @retval #CKMC_ERROR_NONE Successful
* @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid
- * mandatory algorithm parameter, encrypted = NULL,
- * ppdecrypted = NULL)
+ * mandatory algorithm parameter, GCM tag authentication failed, key or data is wrong,
+ * in case of RSA key is wrong or data too long, encrypted = NULL, ppdecrypted = NULL)
* @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in)
* @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason
* @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist
${COMMON_PATH}/common/base64.cpp
${COMMON_PATH}/common/crypto-init.cpp
${COMMON_PATH}/common/data-type.cpp
+ ${COMMON_PATH}/common/openssl-error-handler.cpp
${COMMON_PATH}/common/exception.cpp
${COMMON_PATH}/common/protocols.cpp
${COMMON_PATH}/common/message-buffer.cpp
DefineException<CKM_API_ERROR_INPUT_PARAM, true, PrintDebug>;
using AuthenticationFailed =
DefineException<CKM_API_ERROR_AUTHENTICATION_FAILED, true, PrintDebug>;
+using VerificationFailed =
+ DefineException<CKM_API_ERROR_VERIFICATION_FAILED, true, PrintDebug>;
using InvalidFormat =
DefineException<CKM_API_ERROR_INVALID_FORMAT, true, PrintDebug>;
using BadResponse =
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file openssl-error-handler.cpp
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/dsa.h>
+
+#include <ckm/ckm-error.h>
+#include <dpl/log/log.h>
+
+#include "openssl-error-handler.h"
+#include <exception>
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+#define OPENSSL_SUCCESS 1
+
+namespace CKM {
+
+static const int GENERIC_REASON_MAX = 99;
+
+#define ERRORDESCRIBE(name) case name: return #name
+const char *ckm_debug_translate_error(int err)
+{
+ switch (err) {
+ ERRORDESCRIBE(CKM_API_SUCCESS);
+ ERRORDESCRIBE(CKM_API_ERROR_INPUT_PARAM);
+ ERRORDESCRIBE(CKM_API_ERROR_OUT_OF_MEMORY);
+ ERRORDESCRIBE(CKM_API_ERROR_SERVER_ERROR);
+ ERRORDESCRIBE(CKM_API_ERROR_AUTHENTICATION_FAILED);
+ ERRORDESCRIBE(CKM_API_ERROR_VERIFICATION_FAILED);
+ default: return "Error not defined";
+ }
+}
+#undef ERRORDESCRIBE
+
+void errorDump()
+{
+ BIO *bio = BIO_new(BIO_s_mem());
+ ERR_print_errors(bio);
+ char *buf = NULL;
+ size_t len = BIO_get_mem_data(bio, &buf);
+ BIO_free(bio);
+ std::string ret(buf, len);
+ free(buf);
+ LogError(ret);
+}
+
+void errorHandle(const char *file, int line, const char *function, int openssl_ret)
+{
+ if (openssl_ret >= OPENSSL_SUCCESS)
+ return;
+
+ int ret = CKM_API_SUCCESS;
+
+ unsigned long err = ERR_peek_error();
+
+ if (err == 0)
+ ret = CKM_API_ERROR_SERVER_ERROR;
+
+ /* known errors */
+ switch (err) {
+#if OPENSSL_VERSION_NUMBER > 0x10100000L
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+#else /* OPENSSL_VERSION_NUMBER > 0x10100000L */
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS):
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+#endif /* OPENSSL_VERSION_NUMBER > 0x10100000L */
+ case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION):
+ case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE):
+ case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS):
+ case ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE):
+ case ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE):
+ case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG):
+ case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG):
+ case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT):
+ case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT):
+ case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ):
+ case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ):
+ case ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ):
+ ret = CKM_API_ERROR_INPUT_PARAM;
+ break;
+ case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY):
+ case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE):
+ case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED):
+ ret = CKM_API_ERROR_VERIFICATION_FAILED;
+ break;
+ }
+
+ /* known rsa padding errors */
+ if (ret == CKM_API_SUCCESS && ERR_GET_LIB(err) == ERR_LIB_RSA) {
+ switch (ERR_GET_FUNC(err)) {
+ case RSA_F_CHECK_PADDING_MD:
+ case RSA_F_RSA_PADDING_CHECK_NONE:
+ case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP:
+ case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1:
+ case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1:
+ case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2:
+ case RSA_F_RSA_PADDING_CHECK_SSLV23:
+ case RSA_F_RSA_PADDING_CHECK_X931:
+ case RSA_F_RSA_PADDING_ADD_NONE:
+ case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP:
+ case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1:
+ case RSA_F_RSA_PADDING_ADD_PKCS1_PSS:
+ case RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1:
+ case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1:
+ case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2:
+ case RSA_F_RSA_PADDING_ADD_SSLV23:
+ case RSA_F_RSA_PADDING_ADD_X931:
+ ret = CKM_API_ERROR_INPUT_PARAM;
+ break;
+ }
+ }
+
+ /* fatal errors */
+ int reason = ERR_GET_REASON(err);
+ if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
+ switch (reason) {
+ case ERR_R_MALLOC_FAILURE:
+ ret = CKM_API_ERROR_OUT_OF_MEMORY;
+ break;
+ case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
+ case ERR_R_PASSED_NULL_PARAMETER:
+ ret = CKM_API_ERROR_INPUT_PARAM;
+ break;
+ case ERR_R_INTERNAL_ERROR:
+ case ERR_R_DISABLED:
+ ret = CKM_API_ERROR_SERVER_ERROR;
+ break;
+ }
+ }
+
+ /* neither known nor fatal, unknown */
+ if (ret == CKM_API_SUCCESS) {
+ errorDump();
+ }
+
+ /* remove all errors from queue */
+ ERR_clear_error();
+
+ switch(ret) {
+ case CKM_API_ERROR_INPUT_PARAM:
+ throw CKM::Exc::InputParam(file, function, line, "");
+ case CKM_API_ERROR_OUT_OF_MEMORY:
+ throw CKM::Exc::InternalError(file, function, line, "Out of memory");
+ case CKM_API_ERROR_SERVER_ERROR:
+ throw CKM::Exc::InternalError(file, function, line, "");
+ case CKM_API_ERROR_AUTHENTICATION_FAILED:
+ throw CKM::Exc::AuthenticationFailed(file, function, line, "");
+ case CKM_API_ERROR_VERIFICATION_FAILED:
+ throw CKM::Exc::VerificationFailed(file, function, line, "");
+ default:
+ throw CKM::Exc::InternalError(file, function, line, "Error not described");
+ }
+
+}
+
+} // namespace CKM
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ *
+ * @file openssl-error-handler.h
+ * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ */
+
+#pragma once
+
+#include <ckm/ckm-type.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <sw-backend/obj.h>
+
+#include <symbol-visibility.h>
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+namespace CKM {
+
+COMMON_API void errorDump();
+#define OPENSSL_ERROR_DUMP() errorDump()
+#define OPENSSL_ERROR_CLEAR() ERR_clear_error()
+
+/**
+ * Function responsible for translating the OpenSSL error to CKM error and
+ * clearing/dumping the OpenSSL error queue.
+ *
+ * The function checks only first error in the queue.
+ * If the function doesn't find any error in OpenSSL queue or is not
+ * able to translate it, it will return CKM_API_ERROR_SERVER_ERROR and
+ * dump OpenSSL errors if any. The function clears the error queue and
+ * returns the result of translation.
+ */
+COMMON_API void errorHandle(const char *file, int line, const char *function, int openssl_ret);
+#define OPENSSL_ERROR_HANDLE(openssl_ret) { \
+ ERR_clear_error(); \
+ errorHandle(__FILE__, __LINE__, __func__, openssl_ret); \
+}
+
+} // namespace CKM
\ No newline at end of file
typedef CKM::Exc::InternalError DataTypeNotSupported;
typedef CKM::Exc::InternalError OperationNotSupported;
typedef CKM::Exc::InternalError WrongBackend;
+typedef CKM::Exc::AuthenticationFailed AuthenticationFailed;
} // namespace Exc
} // namespace Crypto
#include <vector>
#include <openssl/evp.h>
+#include <openssl/err.h>
#include <dpl/log/log.h>
#include <dpl/raw-buffer.h>
#include <generic-backend/exception.h>
+#include <openssl-error-handler.h>
+
namespace CKM {
namespace Crypto {
namespace SW {
// Low level api.
// Allows various cipher specific parameters to be determined and set.
- int Control(int type, int arg, void *ptr)
+ void Control(int type, int arg, void *ptr)
{
- return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr);
+ OPENSSL_ERROR_HANDLE(EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr));
}
virtual void AppendAAD(const T &) = 0;
{
if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type))
ThrowErr(Exc::Crypto::InternalError, "Wrong key size! Expected: ",
- EVP_CIPHER_key_length(type), " Get: ", key.size());
+ EVP_CIPHER_key_length(type), " Get: ", key.size());
if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type))
ThrowErr(Exc::Crypto::InternalError, "Wrong iv size! Expected: ",
EVP_CIPHER_iv_length(type), " Get: ", iv.size());
- if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(),
- encryption ? 1 : 0))
- ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherInit");
+ OPENSSL_ERROR_HANDLE(EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(),
+ encryption ? 1 : 0));
EVP_CIPHER_CTX_set_padding(m_ctx, 1);
}
"Unsupported type inside container.");
int bytesLen;
- if (1 != EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size()))
- ThrowErr(Exc::Crypto::InternalError, "AppendAAD(): Failed in EVP_CipherUpdate");
+ OPENSSL_ERROR_HANDLE(EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size()));
}
T Append(const T &data)
int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx));
T output(bytesLen);
- if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(),
- data.size()))
- ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate");
+ OPENSSL_ERROR_HANDLE(EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(),
+ data.size()));
output.resize(bytesLen);
return output;
int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx);
T output(bytesLen);
- if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen))
- ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherFinal");
+ OPENSSL_ERROR_HANDLE(EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen));
output.resize(bytesLen);
return output;
#include <sw-backend/internals.h>
#include <sw-backend/crypto.h>
-#define OPENSSL_SUCCESS 1 // DO NOTCHANGE THIS VALUE
-#define OPENSSL_FAIL 0 // DO NOTCHANGE THIS VALUE
+#include <openssl-error-handler.h>
+
+#define OPENSSL_SUCCESS 1 // DO NOT CHANGE THIS VALUE
+#define OPENSSL_FAIL 0 // DO NOT CHANGE THIS VALUE
namespace CKM {
namespace Crypto {
*/
RawBuffer output;
output.resize(RSA_size(rsa));
- int ret = cryptoFn(data.size(),
- data.data(),
- output.data(),
- rsa,
- RSA_PKCS1_OAEP_PADDING);
- RSA_free(rsa);
-
- if (ret < 0)
- ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed");
+ int ret;
+ try {
+ OPENSSL_ERROR_HANDLE(ret = cryptoFn(data.size(),
+ data.data(),
+ output.data(),
+ rsa,
+ RSA_PKCS1_OAEP_PADDING));
+ } catch (...) {
+ RSA_free(rsa);
+ throw;
+ }
output.resize(ret);
return output;
ThrowErr(Exc::Crypto::InternalError,
"Error in EVP_PKEY_CTX_new_id function !!");
- if (EVP_PKEY_keygen_init(ctx.get()) <= 0)
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_PKEY_keygen_init function !!");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(ctx.get()));
- if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0)
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size));
EVP_PKEY *pkeyTmp = NULL;
- if (!EVP_PKEY_keygen(ctx.get(), &pkeyTmp))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(ctx.get(), &pkeyTmp));
pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
if (!pctx)
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
- if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get()))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_PKEY_paramgen_init function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
- if (EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size));
/* Generate parameters */
EVP_PKEY *pparamTmp = NULL;
- if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp));
pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
if (!kctx)
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
- if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get()))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get()));
/* Generate the key */
EVP_PKEY *pkeyTmp = NULL;
- if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(kctx.get(), &pkeyTmp));
pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
if (!pctx)
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
- if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get()))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_PKEY_paramgen_init function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
- if (EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve));
/* Generate parameters */
EVP_PKEY *pparamTmp = NULL;
- if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp));
pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
if (!kctx)
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
- if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get()))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get()));
/* Generate the key */
EVP_PKEY *pkeyTmp = NULL;
- if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(kctx.get(), &pkeyTmp));
pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
RawBuffer tmp = enc->Finalize();
std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
- if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data()))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in AES control function. Get tag failed.");
+ enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data());
return std::make_pair(result, tag);
}
EvpCipherPtr dec;
selectCipher(type, key.size(), false)(dec, key, iv);
RawBuffer result = dec->Append(data);
- RawBuffer tmp = dec->Finalize();
+ RawBuffer tmp;
+ try {
+ tmp = dec->Finalize();
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InputParam, "Authentication failed in AES finalize function (wrong key/data was used).");
+ }
std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
return result;
}
selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
void *ptr = (void *)tag.data();
- if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in AES control function. Set tag failed.");
+ dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr);
if (!aad.empty())
dec->AppendAAD(aad);
RawBuffer result = dec->Append(data);
- RawBuffer tmp = dec->Finalize();
+ RawBuffer tmp;
+ try {
+ tmp = dec->Finalize();
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InputParam, "Tag authentication failed in AES finalize function (the tag doesn't match).");
+ }
std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
return result;
}
if (!pctx.get())
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
- if (EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS)
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_sign_init(pctx.get()));
/* Set padding algorithm */
if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA)
- if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding))
- ThrowErr(Exc::Crypto::InputParam,
- "Error in EVP_PKEY_CTX_set_rsa_padding function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
/* Finalize the Sign operation */
/* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
* signature. Length is returned in slen */
size_t slen;
- if (EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(),
- message.size()))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size()));
/* Allocate memory for the signature based on size in slen */
RawBuffer sig(slen);
- if (EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
- sig.data(),
- &slen,
- message.data(),
- message.size())) {
- // Set value to return RawData
- sig.resize(slen);
- return sig;
- }
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), sig.data(), &slen, message.data(), message.size()));
- ThrowErr(Exc::Crypto::InputParam,
- "Error in EVP_PKEY_sign function. Input param error.");
+ // Set value to return RawData
+ sig.resize(slen);
+ return sig;
}
RawBuffer digestSignMessage(EVP_PKEY *privKey,
if (!mdctx.get())
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
- if (EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL,
- privKey))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
+ OPENSSL_ERROR_HANDLE(EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey));
/* Set padding algorithm */
if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA)
- if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding))
- ThrowErr(Exc::Crypto::InputParam,
- "Error in EVP_PKEY_CTX_set_rsa_padding function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
/* Call update with the message */
- if (EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(),
- message.size()))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function");
+ OPENSSL_ERROR_HANDLE(EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size()));
/* Finalize the DigestSign operation */
/* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
* signature. Length is returned in slen */
size_t slen;
- if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
+ OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), NULL, &slen));
/* Allocate memory for the signature based on size in slen */
RawBuffer sig(slen);
/* Obtain the signature */
- if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
+ OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen));
// Set value to return RawData
sig.resize(slen);
if (!pctx.get())
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
- if (EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS)
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_verify_init(pctx.get()));
- /* Set padding algorithm */
+ /* Set padding algorithm */
if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA)
- if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding))
- ThrowErr(Exc::Crypto::InputParam,
- "Error in EVP_PKEY_CTX_set_rsa_padding function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
- if (EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
+ if (OPENSSL_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
signature.size(), message.data(), message.size()))
return CKM_API_SUCCESS;
EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
EVP_PKEY_CTX *pctx = NULL;
- /* Create the Message Digest Context */
if (!mdctx.get())
ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
- if (EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL,
- pubKey))
- ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
+ OPENSSL_ERROR_HANDLE(EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey));
if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA)
- if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding))
- ThrowErr(Exc::Crypto::InputParam,
- "Error in EVP_PKEY_CTX_set_rsa_padding function");
+ OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
- if (EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(),
- message.size()))
- ThrowErr(Exc::Crypto::InternalError,
- "Error in EVP_DigestVerifyUpdate function");
+ OPENSSL_ERROR_HANDLE(EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()));
- if (EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(),
+ if (OPENSSL_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(),
const_cast<unsigned char *>(signature.data()), signature.size()))
return CKM_API_SUCCESS;
} // namespace Internals
} // namespace SW
} // namespace Crypto
-} // namespace CKM
-
+} // namespace CKM
\ No newline at end of file
#include <openssl/evp.h>
#include <sw-backend/obj.h>
-#define EVP_SUCCESS 1 // DO NOTCHANGE THIS VALUE
-#define EVP_FAIL 0 // DO NOTCHANGE THIS VALUE
-
#define CKM_CRYPTO_INIT_SUCCESS 1
#define CKM_CRYPTO_CREATEKEY_SUCCESS 2
#define CKM_VERIFY_CHAIN_SUCCESS 5
} // namespace Internals
} // namespace SW
} // namespace Crypto
-} // namespace CKM
-
+} // namespace CKM
\ No newline at end of file
#include <sw-backend/obj.h>
#include <sw-backend/internals.h>
-#define EVP_SUCCESS 1 // DO NOTCHANGE THIS VALUE
-#define EVP_FAIL 0 // DO NOTCHANGE THIS VALUE
-
namespace CKM {
namespace Crypto {
namespace SW {
try {
ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag);
- } catch (const Exc::Crypto::InternalError &e) {
- ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed");
+ } catch (const Exc::Crypto::InputParam &e) {
+ ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed, authentication failed");
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InternalError, "Decryption with custom password failed, internal error");
}
return ret;
try {
ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv,
Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
- } catch (const Exc::Crypto::InternalError &e) {
- ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed");
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InternalError, "Encryption with custom password failed, internal error");
}
scheme |= EncryptionScheme::PASSWORD;
{
DB::Row crow = row;
RawBuffer key;
- RawBuffer result1;
- RawBuffer result2;
crow.algorithmType = DBCMAlgType::AES_GCM_256;
crow.dataSize = crow.data.size();
CLEAR_FLAGS(crow.encryptionScheme);
SET_FLAG(ENCR_APPKEY, crow.encryptionScheme);
- auto dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data,
+ std::pair<RawBuffer, RawBuffer> dataPair;
+ try {
+ dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data,
crow.iv, AES_GCM_TAG_SIZE);
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InternalError, "Encryption failed in encryptRow");
+ }
crow.data = dataPair.first;
crow.tag = dataPair.second;
{
DB::Row crow = row;
RawBuffer key;
- RawBuffer digest, dataDigest;
if (row.algorithmType != DBCMAlgType::AES_GCM_256)
ThrowErr(Exc::AuthenticationFailed, "Invalid algorithm type.");
crow.tag);
}
}
- } catch (const Exc::Exception &e) {
+ } catch (const Exc::Crypto::InputParam &e) {
ThrowErr(Exc::AuthenticationFailed, e.message());
+ } catch (const Exc::Exception &e) {
+ ThrowErr(Exc::InternalError, "Internal error during decryption");
}
if (static_cast<int>(crow.data.size()) < crow.dataSize)