} else {
output << "Running test ";
}
- output << test_unit_type_name(tu) << " \"" << test_unit_name(tu)
+ output << test_unit_type_name(tu) << " \"" << test_unit_name(tu)
<< "\"" << std::endl;
}
/*! \brief indicating that device needed to run API is not supported */
#define CKM_API_ERROR_NOT_SUPPORTED -21
+/*! \brief indicating that Hash(ObjectId) calculation failed */
+#define CKM_API_ERROR_HASH_ERROR -22
+
+
#define CKM_API_OCSP_STATUS_GOOD (1<<0)
#define CKM_API_OCSP_STATUS_UNSUPPORTED (1<<1)
#define CKM_API_OCSP_STATUS_UNKNOWN (1<<2)
/*
- * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2021 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.
* @see #ckmc_cert_s
* @see #ckmc_cert_list_s
*/
-int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckmc_key_s **private_key, ckmc_cert_s **cert, ckmc_cert_list_s **ca_cert_list) TIZEN_DEPRECATED_API;
+int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckmc_key_s **private_key, ckmc_cert_s **cert, ckmc_cert_list_s **ca_cert_list) TIZEN_DEPRECATED_API;
/**
/*
- * Copyright (c) 2015-2019 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2015-2021 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.
#include <ckm/ckm-type.h>
#include <crypto-backend.h>
#include <token.h>
+#include <protocols.h>
+#include <credentials.h>
namespace CKM {
namespace Crypto {
virtual GObjUPtr getObject(const Token &, const Password &) = 0;
virtual TokenPair generateAKey(const CryptoAlgorithm &,
const Password &,
- const Password &) = 0;
- virtual Token generateSKey(const CryptoAlgorithm &, const Password &) = 0;
+ const Password &,
+ const RawBuffer &,
+ const RawBuffer &) = 0;
+
+ virtual Token generateSKey(const CryptoAlgorithm &,
+ const Password &,
+ const RawBuffer &) = 0;
/*
* EncryptionParams parameter makes sense only on device with built-in key.
* EncryptionParams parameter is used for decryption of Data.
* If Data is not encrypted it's ok to pass empty EncryptionParams.
*/
- virtual Token import(const Data &, const Password &, const EncryptionParams &) = 0;
+ virtual Token import(const Data &, const Password &, const EncryptionParams &,
+ const RawBuffer &) = 0;
virtual void destroy(const Token &) = 0;
virtual ~GStore() {}
/*
- * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2021 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.
return SerializeMessage(scheme, packed);
}
+std::string rawToHexString(const RawBuffer &raw)
+{
+ return hexDump<std::string>(raw);
+}
+
} // namespace anonymous
Store::Store(CryptoBackend backendId)
TokenPair Store::generateAKey(const CryptoAlgorithm &algorithm,
const Password &prvPass,
- const Password &pubPass)
+ const Password &pubPass,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
+ LogDebug("Hash of Private key credentials = " << rawToHexString(hashPriv));
+ LogDebug("Hash of Public key credentials = " << rawToHexString(hashPub));
Internals::DataPair ret = Internals::generateAKey(algorithm);
return std::make_pair<Token, Token>(
Token(m_backendId, ret.first.type, pack(ret.first.buffer, prvPass)),
}
Token Store::generateSKey(const CryptoAlgorithm &algorithm,
- const Password &pass)
+ const Password &pass,
+ const RawBuffer &hash)
{
+ LogDebug("Hash of AES Key credentials = " << rawToHexString(hash));
Internals::Data ret = Internals::generateSKey(algorithm);
return Token(m_backendId, ret.type, pack(ret.buffer, pass));
}
-Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e)
+Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e,
+ const RawBuffer &hash)
{
+ LogDebug("Hash of Data credentials = " << rawToHexString(hash));
if (!e.iv.empty())
ThrowErr(Exc::Crypto::OperationNotSupported,
"Encrypted import is not yet supported on software backend!");
/*
- * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2021 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.
explicit Store(CryptoBackend backendId);
virtual GObjUPtr getObject(const Token &, const Password &);
- virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &,
- const Password &);
- virtual Token generateSKey(const CryptoAlgorithm &, const Password &);
- virtual Token import(const Data &data, const Password &, const EncryptionParams &);
+ virtual TokenPair generateAKey(const CryptoAlgorithm &,
+ const Password &,
+ const Password &,
+ const RawBuffer &,
+ const RawBuffer &);
+ virtual Token generateSKey(const CryptoAlgorithm &,
+ const Password &,
+ const RawBuffer &);
+ virtual Token import(const Data &data, const Password &, const EncryptionParams &,
+ const RawBuffer &);
virtual void destroy(const Token &) {}
};
return result;
}
-Data generateSKey(const CryptoAlgorithm &alg,
+void generateSKey(const CryptoAlgorithm &alg,
const Password &pwd,
const RawBuffer &iv,
- RawBuffer &tag)
+ RawBuffer &tag,
+ const RawBuffer &hash)
{
AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
int keyBits = unpack<int>(alg, ParamName::GEN_KEY_LEN);
- Data keyData;
- keyData.type = DataType(KeyType::KEY_AES);
-
if (!pwd.empty()) {
if (iv.empty()) {
ThrowErr(Exc::InputParam, "Key generation with password encryption requires an IV");
RawBuffer pwdBuf(pwd.begin(), pwd.end());
TrustZoneContext::Instance().generateSKeyPwd(getGenSKeyType(keyType),
pwdBuf, iv, keyBits,
- keyData.data, tag);
+ tag, hash);
} else {
TrustZoneContext::Instance().generateSKey(getGenSKeyType(keyType), keyBits,
- keyData.data);
+ hash);
}
- return keyData;
}
-DataPair generateAKey(const CryptoAlgorithm &alg,
+AlgoType generateAKey(const CryptoAlgorithm &alg,
const Password &pubPwd,
const Password &privPwd,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwdIv,
RawBuffer &pubTag,
- RawBuffer &privTag)
+ RawBuffer &privTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE);
int keyBits = unpack<int>(alg, ParamName::GEN_KEY_LEN);
- Data pubKeyData;
- Data privKeyData;
-
RawBuffer pubPwdBuf;
if (!pubPwd.empty())
pubPwdBuf.assign(pubPwd.begin(), pubPwd.end());
switch (keyType) {
case AlgoType::RSA_GEN: {
- pubKeyData.type = DataType(KeyType::KEY_RSA_PUBLIC);
- privKeyData.type = DataType(KeyType::KEY_RSA_PRIVATE);
-
TrustZoneContext::Instance().generateRSAKey(keyBits,
pubPwdBuf,
pubPwdIv,
privPwdBuf,
privPwdIv,
- pubKeyData.data,
pubTag,
- privKeyData.data,
- privTag);
+ privTag,
+ hashPriv,
+ hashPub);
break;
}
case AlgoType::DSA_GEN: {
- pubKeyData.type = DataType(KeyType::KEY_DSA_PUBLIC);
- privKeyData.type = DataType(KeyType::KEY_DSA_PRIVATE);
-
RawBuffer prime;
RawBuffer subprime;
RawBuffer base;
pubPwdIv,
privPwdBuf,
privPwdIv,
- pubKeyData.data,
pubTag,
- privKeyData.data,
- privTag);
+ privTag,
+ hashPriv,
+ hashPub);
break;
}
default: {
}
}
- return DataPair(pubKeyData, privKeyData);
+ return keyType;
}
void destroyKey(const RawBuffer &key)
TrustZoneContext::Instance().executeDestroy(key);
}
-RawBuffer importData(const Data &data,
+void importData(const Data &data,
const EncryptionParams &encData,
const Password &pwd,
const RawBuffer &pwdIV,
- RawBuffer &tag)
+ RawBuffer &tag,
+ const RawBuffer &hash)
{
const auto dataType = toTzDataType(data.type);
- RawBuffer result;
RawBuffer pwdBuf(pwd.begin(), pwd.end());
uint32_t keySizeBits = data.data.size() * 8;
pwdIV,
keySizeBits,
Params::DERIVED_KEY_LENGTH_BITS,
- result,
- tag);
- return result;
+ tag,
+ hash);
}
RawBuffer getData(const RawBuffer &dataId,
RawBuffer generateIV();
-DataPair generateAKey(const CryptoAlgorithm &alg,
+AlgoType generateAKey(const CryptoAlgorithm &alg,
const Password &pubPwd,
const Password &privPwd,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwdIv,
RawBuffer &pubTag,
- RawBuffer &privTag);
+ RawBuffer &privTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub);
-Data generateSKey(const CryptoAlgorithm &alg,
+void generateSKey(const CryptoAlgorithm &alg,
const Password &pwd,
const RawBuffer &iv,
- RawBuffer &tag);
+ RawBuffer &tag,
+ const RawBuffer &hash);
-RawBuffer importData(const Data &key,
+void importData(const Data &key,
const EncryptionParams &encData,
const Password &pwd,
const RawBuffer &pwdIV,
- RawBuffer &tag);
+ RawBuffer &tag,
+ const RawBuffer &hash);
RawBuffer getData(const RawBuffer &dataId,
const Pwd &pwd);
/*
- * Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2021 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.
}
TokenPair Store::generateAKey(const CryptoAlgorithm &alg, const Password &privPass,
- const Password &pubPass)
+ const Password &pubPass, const RawBuffer &hashPriv, const RawBuffer &hashPub)
{
RawBuffer pubIv, privIv;
RawBuffer pubTag, privTag;
privIv = Internals::generateIV();
}
- Internals::DataPair ret = Internals::generateAKey(alg, pubPass, privPass, pubIv, privIv, pubTag, privTag);
+ AlgoType keyType;
+ DataType pubType, privType;
+ keyType = Internals::generateAKey(alg, pubPass, privPass, pubIv, privIv, pubTag, privTag, hashPriv, hashPub);
+ if(keyType == AlgoType::RSA_GEN){
+ pubType = DataType(KeyType::KEY_RSA_PUBLIC);
+ privType = DataType(KeyType::KEY_RSA_PRIVATE);
+ }
+ else if(keyType == AlgoType::DSA_GEN){
+ pubType= DataType(KeyType::KEY_DSA_PUBLIC);
+ privType = DataType(KeyType::KEY_DSA_PRIVATE);
+ }
return std::make_pair<Token, Token>(
- Token(m_backendId, ret.second.type, pack(ret.second.data, privPass, privIv, privTag)),
- Token(m_backendId, ret.first.type, pack(ret.first.data, pubPass, pubIv, pubTag))
+ Token(m_backendId, privType, pack(hashPriv, privPass, privIv, privTag)),
+ Token(m_backendId, pubType, pack(hashPub, pubPass, pubIv, pubTag))
);
}
-Token Store::generateSKey(const CryptoAlgorithm &alg, const Password &pass)
+Token Store::generateSKey(const CryptoAlgorithm &alg,
+ const Password &pass,
+ const RawBuffer &hash)
{
RawBuffer iv;
RawBuffer tag;
iv = Internals::generateIV();
}
- Data ret = Internals::generateSKey(alg, pass, iv, tag);
- return Token(m_backendId, ret.type, pack(ret.data, pass, iv, tag));
+ Internals::generateSKey(alg, pass, iv, tag, hash);
+ return Token(m_backendId, DataType(KeyType::KEY_AES), pack(hash, pass, iv, tag));
}
-Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e)
+Token Store::import(const Data &data, const Password &pass, const EncryptionParams &e,
+ const RawBuffer &hash)
{
if (!data.type.isBinaryData() && !data.type.isKey())
ThrowErr(Exc::Crypto::DataTypeNotSupported, "Invalid data provided for import");
passIV = Internals::generateIV();
}
- RawBuffer dataId = Internals::importData(data, e, pass, passIV, tag);
- return Token(m_backendId, data.type, pack(dataId, pass, passIV, tag));
+ Internals::importData(data, e, pass, passIV, tag, hash);
+ return Token(m_backendId, data.type, pack(hash, pass, passIV, tag));
}
void Store::destroy(const Token &token)
/*
- * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 2021 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.
explicit Store(CryptoBackend backendId);
virtual GObjUPtr getObject(const Token &, const Password &);
- virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &,
- const Password &);
- virtual Token generateSKey(const CryptoAlgorithm &, const Password &);
- virtual Token import(const Data &, const Password &, const EncryptionParams &);
+ virtual TokenPair generateAKey(const CryptoAlgorithm &,
+ const Password &,
+ const Password &,
+ const RawBuffer &,
+ const RawBuffer &);
+ virtual Token generateSKey(const CryptoAlgorithm &,
+ const Password &,
+ const RawBuffer &);
+ virtual Token import(const Data &, const Password &, const EncryptionParams &,
+ const RawBuffer &);
virtual void destroy(const Token &);
// TODO device key ID is needed here to support importEncrypted
void TrustZoneContext::generateSKey(tz_algo_type algo,
uint32_t keySizeBits,
- RawBuffer &keyId)
+ const RawBuffer &hash)
{
// command ID = CMD_GENERATE_KEY
- TZSerializer sOut;
- sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
-
- TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
+ TZSerializer sIn;
+ sIn.Push(new TZSerializableBinary(hash));
+ TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
+ sIn.Serialize(inMemory);
TEEC_Operation op;
op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
TEEC_NONE, TEEC_NONE);
op.params[0].value.a = algo;
op.params[0].value.b = keySizeBits;
- op.params[1].memref.parent = outMemory.Get();
+ op.params[1].memref.parent = inMemory.Get();
op.params[1].memref.offset = 0;
- op.params[1].memref.size = outMemory.Get()->size;
+ op.params[1].memref.size = inMemory.Get()->size;
Execute(CMD_GENERATE_KEY, &op);
-
- sOut.Deserialize(outMemory);
- sOut.Pull(keyId);
}
void TrustZoneContext::generateSKeyPwd(tz_algo_type algo,
const RawBuffer &pwd,
const RawBuffer &iv,
const uint32_t keySizeBits,
- RawBuffer &keyId,
- RawBuffer &pwdTag)
+ RawBuffer &pwdTag,
+ const RawBuffer &hash)
{
// command ID = CMD_GENERATE_KEY_PWD
TZSerializer sIn;
sIn.Push(new TZSerializablePwdData(pwd, iv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
+ sIn.Push(new TZSerializableBinary(hash));
TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
sIn.Serialize(inMemory);
TZSerializer sOut;
- sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
sOut.Push(new TZSerializableBinary(Params::DEFAULT_AES_GCM_TAG_LEN_BYTES));
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
Execute(CMD_GENERATE_KEY_PWD, &op);
sOut.Deserialize(outMemory);
- sOut.Pull(keyId);
sOut.Pull(pwdTag);
+
+ if (pwdTag.size() != Params::DEFAULT_AES_GCM_TAG_LEN_BYTES) {
+ ThrowErr(Exc::Crypto::InternalError, "Deserialized incorrect key tag");
+ }
}
void TrustZoneContext::GenerateAKey(tz_command commandId,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag)
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
uint32_t pubTagSize = 0;
uint32_t privTagSize = 0;
sIn.Push(new TZSerializablePwdData(privPwd, privPwdIv, Params::DEFAULT_AES_GCM_TAG_LEN_BITS));
privTagSize = (Params::DEFAULT_AES_GCM_TAG_LEN_BITS + 7) >> 3;
}
-
+ sIn.Push(new TZSerializableBinary(hashPriv));
+ sIn.Push(new TZSerializableBinary(hashPub));
TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
sIn.Serialize(inMemory);
TZSerializer sOut;
- sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
- if (pubTagSize) {
- sOut.Push(new TZSerializableBinary(pubTagSize));
- }
- sOut.Push(new TZSerializableBinary(KM_KEY_ID_SIZE));
- if (privTagSize) {
- sOut.Push(new TZSerializableBinary(privTagSize));
- }
+ sOut.Push(new TZSerializableBinary(pubTagSize));
+ sOut.Push(new TZSerializableBinary(privTagSize));
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
Execute(commandId, &op);
sOut.Deserialize(outMemory);
-
- sOut.Pull(pubKeyId);
-
if (pubPwdExists) {
sOut.Pull(pubKeyTag);
}
- sOut.Pull(privKeyId);
-
if (privPwdExists) {
sOut.Pull(privKeyTag);
}
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag)
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
// command ID = CMD_GENERATE_RSA_KEYPAIR
TZSerializer sIn;
pubPwdIv,
privPwd,
privPwdIv,
- pubKeyId,
pubKeyTag,
- privKeyId,
- privKeyTag);
+ privKeyTag,
+ hashPriv,
+ hashPub);
}
void TrustZoneContext::generateDSAKey(uint32_t keySizeBits,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag)
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub)
{
// command ID = CMD_GENERATE_DSA_KEYPAIR
TZSerializer sIn;
pubPwdIv,
privPwd,
privPwdIv,
- pubKeyId,
pubKeyTag,
- privKeyId,
- privKeyTag);
+ privKeyTag,
+ hashPriv,
+ hashPub);
}
void TrustZoneContext::executeCrypt(tz_command cmd,
const RawBuffer &iv,
const uint32_t keySizeBits,
const uint32_t pwdTagSizeBits,
- RawBuffer &dataId,
- RawBuffer &pwdTag)
+ RawBuffer &pwdTag,
+ const RawBuffer &hash)
{
// command ID = CMD_IMPORT_DATA
+ LogDebug("TrustZoneContext::importData data size = [" << data.size() << "]");
TZSerializer sIn;
sIn.Push(new TZSerializableFlag(dataType));
sIn.Push(new TZSerializableBinary(data));
if (pwd_flag)
sIn.Push(new TZSerializablePwdData(pwd, iv, pwdTagSizeBits));
+ sIn.Push(new TZSerializableBinary(hash));
+
TrustZoneMemory inMemory(m_Context, sIn.GetSize(), TEEC_MEM_INPUT);
sIn.Serialize(inMemory);
TZSerializer sOut;
- sOut.Push(new TZSerializableBinary(KM_DATA_ID_SIZE));
if (pwd_flag) {
sOut.Push(new TZSerializableBinary(pwdTagSizeBits / 8));
}
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
TEEC_Operation op;
- op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
+ if (pwd_flag) {
+ op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
TEEC_MEMREF_WHOLE, TEEC_NONE);
+ }
+ else {
+ op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_MEMREF_WHOLE,
+ TEEC_NONE, TEEC_NONE);
+ }
+
op.params[1].memref.parent = inMemory.Get();
op.params[1].memref.offset = 0;
op.params[1].memref.size = inMemory.Get()->size;
Execute(CMD_IMPORT_DATA, &op);
- sOut.Deserialize(outMemory);
- sOut.Pull(dataId);
if (pwd_flag) {
+ sOut.Deserialize(outMemory);
sOut.Pull(pwdTag);
}
- LogDebug("Imported object ID is (hex): " << rawToHexString(dataId));
+ LogDebug("Imported object ID is (hex): " << rawToHexString(hash));
}
void TrustZoneContext::GetDataSize(const RawBuffer &dataId, uint32_t &dataSize)
uint32_t data_size = 0;
GetDataSize(dataId, data_size);
+ LogDebug("GetData data_size = [" << data_size << "]");
+
TZSerializer sOut;
sOut.Push(new TZSerializableBinary(data_size));
TrustZoneMemory outMemory(m_Context, sOut.GetSize(), TEEC_MEM_OUTPUT);
void generateIV(RawBuffer &iv);
void generateSKey(tz_algo_type algo,
uint32_t keySizeBits,
- RawBuffer &keyId);
+ const RawBuffer &hash);
void generateSKeyPwd(tz_algo_type algo,
const RawBuffer &pwd,
const RawBuffer &iv,
const uint32_t pwdKeySizeBits,
- RawBuffer &keyId,
- RawBuffer &pwdTag);
+ RawBuffer &pwdTag,
+ const RawBuffer &hash);
void generateRSAKey(uint32_t keySizeBits,
const RawBuffer &pubPwd,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag);
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub);
void generateDSAKey(uint32_t keySizeBits,
const RawBuffer &prime,
const RawBuffer &subprime,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag);
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub);
void importData(uint32_t dataType,
const RawBuffer &data,
const RawBuffer &pwdIV,
const uint32_t keySizeBits,
const uint32_t powTagSizeBits,
- RawBuffer &keyId,
- RawBuffer &pwdTag);
+ RawBuffer &pwdTag,
+ const RawBuffer &hash);
void executeCrypt(tz_command cmd,
tz_algo_type algo,
const RawBuffer &pubPwdIv,
const RawBuffer &privPwd,
const RawBuffer &privPwdIv,
- RawBuffer &pubKeyId,
RawBuffer &pubKeyTag,
- RawBuffer &privKeyId,
- RawBuffer &privKeyTag);
+ RawBuffer &privKeyTag,
+ const RawBuffer &hashPriv,
+ const RawBuffer &hashPub);
TEEC_Context m_Context;
TEEC_Session m_Session;
m_SharedMemory.flags = flags;
LogDebug("Allocating " << size << " bytes of shared TZ memory, flags: " << flags);
- TEEC_Result result = TEEC_AllocateSharedMemory(&context, &m_SharedMemory);
- if (result != TEEC_SUCCESS) {
+ if(size != 0) {
+ TEEC_Result result = TEEC_AllocateSharedMemory(&context, &m_SharedMemory);
+ if (result != TEEC_SUCCESS) {
ThrowErr(Exc::Crypto::InternalError, "TZ failed to register memory: ",
static_cast<uint32_t>(result));
+ }
+ memset(m_SharedMemory.buffer, 0, m_SharedMemory.size);
+ }
+ else {
+ m_SharedMemory.buffer = NULL;
+ m_SharedMemory.size = 0;
}
- memset(m_SharedMemory.buffer, 0, m_SharedMemory.size);
}
TEEC_SharedMemory* TrustZoneMemory::Get() const
void TrustZoneMemory::Release()
{
- TEEC_ReleaseSharedMemory(&m_SharedMemory);
+ if(m_SharedMemory.size != 0)
+ TEEC_ReleaseSharedMemory(&m_SharedMemory);
}
} // namespace Internals
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014-2021 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.
int tryRet(F &&f)
{
try {
- static_assert(sizeof(int) == sizeof std::forward<F>(f)());
+ static_assert(std::is_same_v<decltype(std::forward<F>(f)()), int>);
return std::forward<F>(f)();
} catch (const Exc::Exception &e) {
return e.error();
return CKM_API_ERROR_INPUT_PARAM;
}
- output = std::move(Crypto::Data(input.type, output_key->getDER()));
+ output = Crypto::Data(input.type, output_key->getDER());
} else if (input.type.isCertificate() || input.type.isChainCert()) {
CertificateShPtr cert = CKM::Certificate::create(input.data,
DataFormat::FORM_DER);
return CKM_API_ERROR_INPUT_PARAM;
}
- output = std::move(Crypto::Data(input.type, cert->getDER()));
+ output = Crypto::Data(input.type, cert->getDER());
} else {
output = input;
}
const Name &name,
const ClientId &owner,
const Crypto::Data &data,
- const Policy &policy)
+ const Policy &policy,
+ const RawBuffer &hash)
{
Crypto::GStore &store = m_decider.getStore(data.type, policy);
// do not encrypt data with password during cc_mode on
Token token = store.import(data,
m_accessControl.isCCMode() ? "" : policy.password,
- Crypto::EncryptionParams());
+ Crypto::EncryptionParams(), hash);
DB::Row row(std::move(token), name, owner,
static_cast<int>(policy.extractable));
crypto.encryptRow(row);
const PKCS12Serializable &pkcs,
const PolicySerializable &keyPolicy,
const PolicySerializable &certPolicy,
- DB::RowVector &output)
+ DB::RowVector &output,
+ const Credentials &cred)
{
// private key is mandatory
auto key = pkcs.getKey();
return CKM_API_ERROR_INVALID_FORMAT;
}
+ auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
+ if (digest.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
Crypto::Data keyData(DataType(key->getType()), key->getDER());
int retCode = verifyBinaryData(keyData);
return retCode;
output.push_back(createEncryptedRow(crypto, name, owner, keyData,
- keyPolicy));
+ keyPolicy, digest));
// certificate is mandatory
auto cert = pkcs.getCertificate();
return retCode;
output.push_back(createEncryptedRow(crypto, name, owner, certData,
- certPolicy));
+ certPolicy, digest));
// CA cert chain
unsigned int cert_index = 0;
return retCode;
output.push_back(createEncryptedRow(crypto, name, owner, caCertData,
- certPolicy));
+ certPolicy, digest));
}
return CKM_API_SUCCESS;
Crypto::GObjUPtr CKMLogic::rowToObject(
UserData &handler,
DB::Row row,
- const Password &password)
+ const Password &password,
+ const RawBuffer &hash)
{
Crypto::GStore &store = m_decider.getStore(row);
store.destroy(row);
// import it to store with new scheme: data -> pass(data)
- Token token = store.import(Crypto::Data(row.dataType, row.data), pass, Crypto::EncryptionParams());
+ Token token = store.import(Crypto::Data(row.dataType, row.data), pass, Crypto::EncryptionParams(), hash);
// get it from the store (it can be different than the data we imported into store)
obj = store.getObject(token, pass);
if (CKM_API_SUCCESS != retCode)
return retCode;
+ auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
+ if (digest.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
// decrypt row
for (auto &row : rows)
- objs.push_back(rowToObject(handler, std::move(row), password));
+ objs.push_back(rowToObject(handler, std::move(row), password, digest));
// rowToObject may modify db
transaction.commit();
if (CKM_API_SUCCESS != retCode)
return retCode;
- obj = rowToObject(handler, std::move(row), password);
+ auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
+ if (digest.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
+ obj = rowToObject(handler, std::move(row), password, digest);
// rowToObject may modify db
transaction.commit();
// Inital values are always imported with root credentials. Client id is not important.
Credentials rootCred(0, "");
-
+ ClientId owner(CLIENT_ID_SYSTEM);
auto &handler = selectDatabase(rootCred, CLIENT_ID_SYSTEM);
// check if save is possible
Crypto::GStore &store =
m_decider.getStore(data.type, policy, !encParams.iv.empty());
- Token token;
+ Token token;
+
+ auto digest = CryptoLogic::makeHash(name, owner, rootCred.clientUid);
+ if (digest.empty())
+ return CKM_API_ERROR_HASH_ERROR;
- if (encParams.iv.empty()) {
- // Data are not encrypted, let's try to verify them
- Crypto::Data binaryData;
+ if (encParams.iv.empty()) {
+ // Data are not encrypted, let's try to verify them
+ Crypto::Data binaryData;
if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
return retCode;
- token = store.import(binaryData,
- m_accessControl.isCCMode() ? "" : policy.password,
- encParams);
- } else {
- token = store.import(data,
- m_accessControl.isCCMode() ? "" : policy.password,
- encParams);
- }
+ token = store.import(binaryData,
+ m_accessControl.isCCMode() ? "" : policy.password,
+ encParams, digest);
+ } else {
+ token = store.import(data,
+ m_accessControl.isCCMode() ? "" : policy.password,
+ encParams, digest);
+ }
DB::Row row(std::move(token), name, CLIENT_ID_SYSTEM,
static_cast<int>(policy.extractable));
if (retCode != CKM_API_SUCCESS)
return retCode;
+ auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
+ if (digest.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
// save the data
DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, owner,
- data, policy);
+ data, policy, digest);
handler.database.saveRow(encryptedRow);
transaction.commit();
// extract and encrypt the data
DB::RowVector encryptedRows;
retCode = extractPKCS12Data(handler.crypto, name, owner, pkcs, keyPolicy,
- certPolicy, encryptedRows);
+ certPolicy, encryptedRows, cred);
if (retCode != CKM_API_SUCCESS)
return retCode;
if (retCode != CKM_API_SUCCESS)
return retCode;
+ auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
+ if (digest.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
// create key in store
CryptoAlgorithm keyGenAlgorithm;
keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
Token key = m_decider.getStore(DataType::KEY_AES,
- policy).generateSKey(keyGenAlgorithm, policy.password);
+ policy).generateSKey(keyGenAlgorithm, policy.password, digest);
// save the data
DB::Row row(std::move(key), name, owner,
bool exportable = policyPrivate.extractable || policyPublic.extractable;
Policy lessRestricted(Password(), exportable, policyPrivate.backend);
+ auto digestPriv = CryptoLogic::makeHash(namePrivate, explicitOwnerPrivate, cred.clientUid);
+ if (digestPriv.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
+ auto digestPub = CryptoLogic::makeHash(namePublic, explicitOwnerPublic, cred.clientUid);
+ if (digestPub.empty())
+ return CKM_API_ERROR_HASH_ERROR;
+
TokenPair keys = m_decider.getStore(policyPrivate, dt.first, dt.second).generateAKey(keyGenParams,
policyPrivate.password,
- policyPublic.password);
+ policyPublic.password,
+ digestPriv, digestPub);
DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
// in case the same database is used for private and public - the second
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014-2021 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.
const Policy &policy);
int unlockSystemDB();
-
private:
// select private/system database depending on asking uid and owner id.
// output: database handler for effective owner
const Name &name,
const ClientId &owner,
const Crypto::Data &data,
- const Policy &policy);
+ const Policy &policy,
+ const RawBuffer &hash);
int getPKCS12Helper(
const Credentials &cred,
const PKCS12Serializable &pkcs,
const PolicySerializable &keyPolicy,
const PolicySerializable &certPolicy,
- DB::RowVector &output);
+ DB::RowVector &output,
+ const Credentials &cred);
int removeDataHelper(
const Credentials &cred,
Crypto::GObjUPtr rowToObject(
UserData &handler,
DB::Row row,
- const Password &password);
-
+ const Password &password,
+ const RawBuffer &hash);
protected:
int readDataHelper(
bool exportFlag,
/*
- * Copyright (c) 2014 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014 - 2021 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.
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include <openssl/sha.h>
#include <ckm/ckm-error.h>
data = std::move(decdata);
}
+RawBuffer CryptoLogic::makeHash(
+ const std::string& name,
+ const std::string& owner,
+ uid_t uid)
+{
+ const std::string msg = name + owner + std::to_string(uid);
+ RawBuffer digest(SHA512_DIGEST_LENGTH);
+ auto msg_ptr = reinterpret_cast<const unsigned char*>(msg.data());
+
+ if (!SHA512(msg_ptr, msg.length(), digest.data()))
+ return RawBuffer();
+
+ return digest;
+}
+
} // namespace CKM
/*
- * Copyright (c) 2014 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014 - 2021 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.
const RawBuffer &applicationKey);
void removeKey(const ClientId &client);
+ static RawBuffer makeHash(
+ const std::string& name,
+ const std::string& owner,
+ uid_t uid);
+
/*
* v1 encryption.
* Token returned from store is encrypted with app key and
void encBase64(RawBuffer &data);
};
+
} // namespace CKM
/*
- * Copyright (c) 2017 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 2021 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.
#include <cstdlib>
#include <time.h>
#include <boost_macros_wrapper.h>
-
#include "test_common.h"
using namespace CKM;
constexpr char TEST_CLIENT[] = "test_client";
constexpr char TEST_NAME[] = "test_name";
+constexpr uid_t TEST_UID = 0;
const auto TEST_KEY = createRandom(32);
const auto TEST_DATA = createRandom(10);
Crypto::Data data(DataType::BINARY_DATA, TEST_DATA);
Crypto::Decider decider;
Crypto::GStore &store = decider.getStore(data.type, policy);
- Token token = store.import(data, policy.password, Crypto::EncryptionParams());
+
+ const auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_CLIENT, TEST_UID);
+ BOOST_REQUIRE(!digest.empty());
+
+ Token token = store.import(data, policy.password, Crypto::EncryptionParams(), digest);
DB::Row row(token, TEST_NAME, TEST_CLIENT, static_cast<int>(policy.extractable));
Crypto::Data data(DataType::BINARY_DATA, TEST_DATA);
Crypto::Decider decider;
Crypto::GStore &store = decider.getStore(data.type, policy);
- Token token = store.import(data, policy.password, Crypto::EncryptionParams());
+
+ const auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_CLIENT, TEST_UID);
+ BOOST_REQUIRE(!digest.empty());
+
+ Token token = store.import(data, policy.password, Crypto::EncryptionParams(), digest);
DB::Row row(token, TEST_NAME, TEST_CLIENT, static_cast<int>(policy.extractable));
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2020 - 2021 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.
#include <data-type.h>
#include <ckm/ckm-key.h>
#include <ckm/ckm-type.h>
+#include <crypto-logic.h>
#include <generic-backend/crypto-params.h>
using namespace CKM;
namespace {
+const Name TEST_NAME = "test_data";
+const Name TEST_NAME2 = "test_data2";
+const ClientId TEST_OWNER = "test_owner";
+const uid_t TEST_UID = 0;
+
Store STORE(CryptoBackend::OpenSSL);
+RawBuffer makeTestDigest()
+{
+ auto digest = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID);
+ BOOST_REQUIRE(!digest.empty());
+ return digest;
+}
+
+std::pair<RawBuffer, RawBuffer> makePubPrivTestDigest()
+{
+ auto digestPub = CryptoLogic::makeHash(TEST_NAME, TEST_OWNER, TEST_UID);
+ auto digestPriv = CryptoLogic::makeHash(TEST_NAME2, TEST_OWNER, TEST_UID);
+ BOOST_REQUIRE(!digestPub.empty() && !digestPriv.empty());
+ return std::make_pair(std::move(digestPub), std::move(digestPriv));
+}
+
void checkKey(const Token& token, KeyType keyType, const Password& pass)
{
DataType dataType(keyType);
gen.setParam(ParamName::GEN_EC, param);
else
gen.setParam(ParamName::GEN_KEY_LEN, param);
- auto keyPair = STORE.generateAKey(gen, "", "");
+
+ const auto [digestPub, digestPriv] = makePubPrivTestDigest();
+
+ auto keyPair = STORE.generateAKey(gen, "", "", digestPriv, digestPub);
GObjUPtrPair pair;
BOOST_REQUIRE_NO_THROW(pair.prv = STORE.getObject(keyPair.first, ""));
ca.setParam(ParamName::GEN_KEY_LEN, len);
Token token;
- BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, ""));
+
+ const auto digest = makeTestDigest();
+
+ BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, "", digest));
GObjUPtr obj;
BOOST_REQUIRE_NO_THROW(obj = STORE.getObject(token, ""));
auto& types = algo2types.at(algo);
TokenPair tokenPair;
- BOOST_REQUIRE_NO_THROW(tokenPair = STORE.generateAKey(ca, prvPass, pubPass));
+
+ const auto [digestPub, digestPriv] = makePubPrivTestDigest();
+
+ BOOST_REQUIRE_NO_THROW(tokenPair = STORE.generateAKey(ca, prvPass, pubPass, digestPriv, digestPub));
checkKey(tokenPair.first, types.first, prvPass);
checkKey(tokenPair.second, types.second, pubPass);
};
auto invalidGen = [&]
{
- BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", ""), Exc::Crypto::InputParam);
+ const auto [digestPub, digestPriv] = makePubPrivTestDigest();
+ BOOST_REQUIRE_THROW(STORE.generateAKey(*ca, "", "", digestPriv, digestPub), Exc::Crypto::InputParam);
};
invalidGen();
auto testSKey = [&](const Password& pass = "")
{
Token token;
- BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass));
+ const auto digest = makeTestDigest();
+ BOOST_REQUIRE_NO_THROW(token = STORE.generateSKey(ca, pass, digest));
checkKey(token, KeyType::KEY_AES, pass);
};
auto invalidGen = [&]
{
- BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, ""), Exc::Crypto::InputParam);
+ const auto digest = makeTestDigest();
+ BOOST_REQUIRE_THROW(STORE.generateSKey(*ca, "", digest), Exc::Crypto::InputParam);
};
invalidGen();
* happens to be a valid padding. In such case make sure that the length of the
* decrypted data is different.
*/
+
BOOST_REQUIRE(decrypted.size() != data.size());
} catch (const Exc::Crypto::InputParam&) {
// This is fine
Data data(DataType::BINARY_DATA, buffer);
EncryptionParams ep;
Token token;
- BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep));
+ const auto digest = makeTestDigest();
+
+ BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
BOOST_REQUIRE(token.backendId == CryptoBackend::OpenSSL);
BOOST_REQUIRE(token.dataType == data.type);
BOOST_REQUIRE(!token.data.empty());
Data data(DataType::BINARY_DATA, createRandom(16));
EncryptionParams ep;
ep.iv = createRandom(16);
- BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep), Exc::Crypto::OperationNotSupported);
+ const auto digest = makeTestDigest();
+
+ BOOST_REQUIRE_THROW(STORE.import(data, "pass", ep, digest), Exc::Crypto::OperationNotSupported);
}
NEGATIVE_TEST_CASE(getObject)
Data data(DataType::BINARY_DATA, createRandom(16));
EncryptionParams ep;
Token token;
- BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep));
+ const auto digest = makeTestDigest();
+
+ BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "pass", ep, digest));
BOOST_REQUIRE_THROW(STORE.getObject(token, "wrongpass"), Exc::Crypto::AuthenticationFailed);
EncryptionParams ep;
Data data(DataType::CERTIFICATE, cert.getBinary());
Token token;
- BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep));
+ const auto digest = makeTestDigest();
+
+ BOOST_REQUIRE_NO_THROW(token = STORE.import(data, "", ep, digest));
BOOST_REQUIRE(token.dataType == DataType::CERTIFICATE);
GObjUPtr obj;