switch (info.objectType) {
case TEE_TYPE_RSA_KEYPAIR:
case TEE_TYPE_DSA_KEYPAIR:
+ case TEE_TYPE_ECDSA_KEYPAIR:
return 1;
default: break;
};
switch (info.objectType) {
case TEE_TYPE_RSA_PUBLIC_KEY:
case TEE_TYPE_DSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
return 1;
default: break;
};
}
- LOGD("Invalid key type provided for given command");
+ LOGD("Invalid key type provided for given command. objectType=%x", info.objectType);
return 0;
}
return 0;
}
}
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_KEYPAIR: {
+ switch (key_size) {
+ case 192:
+ case 256:
+ case 384:
+ return 1;
+ default:
+ return 0;
+ }
+ }
default:
LOG("Invalid key type provided: %x", type);
return 0;
}
}
case ALGO_ECDSA_SV: {
- // TODO unsupported in GP API 1.0
- return 0;
+ switch (hash) {
+ case HASH_SHA1: return TEE_ALG_ECDSA_P192;
+ case HASH_SHA256: return TEE_ALG_ECDSA_P256;
+ case HASH_SHA384: return TEE_ALG_ECDSA_P384;
+ case HASH_SHA512: return TEE_ALG_ECDSA_P521;
+ default: return 0;
+ }
}
default: return 0;
}
return ret;
}
-static TEE_Result KM_AllocateObjId(KM_BinaryData *objId)
+static TEE_Result KM_ToTeeEccCurve(uint32_t curve, uint32_t *id)
{
- if (objId == NULL) {
- LOG("objId is NULL");
- return TEE_ERROR_GENERIC;
+ switch(curve) {
+ case EC_NIST_P192: *id = TEE_ECC_CURVE_NIST_P192; break;
+ case EC_NIST_P256: *id = TEE_ECC_CURVE_NIST_P256; break;
+ case EC_NIST_P384: *id = TEE_ECC_CURVE_NIST_P384; break;
+ default: return TEE_ERROR_BAD_PARAMETERS;
}
+ return TEE_SUCCESS;
+}
- objId->data_size = KM_KEY_ID_SIZE;
- objId->data = malloc(objId->data_size);
-
- if (objId->data == NULL) {
- LOG("Failed to allocate object ID buffer");
- return TEE_ERROR_OUT_OF_MEMORY;
+static TEE_Result KM_ToKeyBitSize(uint32_t curve, uint32_t *bitsize)
+{
+ switch(curve) {
+ case EC_NIST_P192: *bitsize = 192; break;
+ case EC_NIST_P256: *bitsize = 256; break;
+ case EC_NIST_P384: *bitsize = 384; break;
+ default: return TEE_ERROR_BAD_PARAMETERS;
}
-
return TEE_SUCCESS;
}
sizeof(dsaParams) / sizeof(*dsaParams));
}
+TEE_Result KM_ExecCmdGenerateECKey(TEE_Param param[4])
+{
+ TEE_Attribute ecParams[1];
+ uint32_t curve;
+ uint32_t keyBitSize;
+ int ret;
+
+ ret = KM_ToTeeEccCurve(param[0].value.b, &curve);
+ if (ret) {
+ LOG("Failed to convert curve, input = %d", param[0].value.b);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ ret = KM_ToKeyBitSize(param[0].value.b, &keyBitSize);
+ if (ret) {
+ LOG("Failed to convert to keyBitSize, input = %d", param[0].value.b);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ KM_InitValueAttribute(&ecParams[0], TEE_ATTR_ECC_CURVE, 0, (uint32_t) curve);
+
+ return KM_GenerateAsymKey(param[1].memref.buffer,
+ param[1].memref.size,
+ param[2].memref.buffer,
+ param[2].memref.size,
+ TEE_TYPE_ECDSA_KEYPAIR,
+ TEE_TYPE_ECDSA_PUBLIC_KEY,
+ keyBitSize,
+ ecParams,
+ sizeof(ecParams) / sizeof(*ecParams));
+}
+
TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
TEE_ATTR_DSA_PUBLIC_VALUE,
};
+const uint32_t ECC_PRIVATE_ATTRIBUTES[] = {
+ TEE_ATTR_ECC_CURVE,
+ TEE_ATTR_ECC_PRIVATE_VALUE,
+ TEE_ATTR_ECC_PUBLIC_VALUE_X,
+ TEE_ATTR_ECC_PUBLIC_VALUE_Y,
+};
+
+const uint32_t ECC_PUBLIC_ATTRIBUTES[] = {
+ TEE_ATTR_ECC_CURVE,
+ TEE_ATTR_ECC_PUBLIC_VALUE_X,
+ TEE_ATTR_ECC_PUBLIC_VALUE_Y,
+};
+
#define arraySize(A) (sizeof(A) / sizeof(A[0]))
#define RSA_PRIVATE_ATTRIBUTES_SIZE arraySize(RSA_PRIVATE_ATTRIBUTES)
#define RSA_PUBLIC_ATTRIBUTES_SIZE arraySize(RSA_PUBLIC_ATTRIBUTES)
#define DSA_PRIVATE_ATTRIBUTES_SIZE arraySize(DSA_PRIVATE_ATTRIBUTES)
#define DSA_PUBLIC_ATTRIBUTES_SIZE arraySize(DSA_PUBLIC_ATTRIBUTES)
+#define ECC_PRIVATE_ATTRIBUTES_SIZE arraySize(ECC_PRIVATE_ATTRIBUTES)
+#define ECC_PUBLIC_ATTRIBUTES_SIZE arraySize(ECC_PUBLIC_ATTRIBUTES)
#define MAX_ATTRIBUTES_SIZE (\
RSA_PRIVATE_ATTRIBUTES_SIZE > DSA_PRIVATE_ATTRIBUTES_SIZE\
}
}
+static inline bool isValueAttr(uint32_t attrId)
+{
+ // bit[29] == 1 -> value type attribute, not a buffer attribute.
+ if (attrId & TEE_ATTR_FLAG_VALUE)
+ return true;
+ else
+ return false;
+}
+
static TEE_Result KM_CreateTransientObject(uint32_t object_type,
uint32_t max_object_size,
TEE_Attribute attr[],
TEE_ObjectHandle *hndl)
{
TEE_Result ret = TEE_SUCCESS;
+ uint32_t max_object_size = key_bits_size;
+
+ switch (tee_key_type) {
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ // Give enough room for generated keys in private format
+ max_object_size = key_bits_size * 8;
+ break;
+ }
- ret = TEE_AllocateTransientObject(tee_key_type, key_bits_size, hndl);
+ ret = TEE_AllocateTransientObject(tee_key_type, max_object_size, hndl);
if (TEE_SUCCESS != ret) {
LOG("TEE_AllocateTransientObject has failed with=%x. key_type = %x size_bits = %u",
ret, tee_key_type, key_bits_size);
TEE_ObjectHandle srcHndl, TEE_ObjectHandle *dstHndl)
{
TEE_Result ret = TEE_SUCCESS;
+ uint32_t max_object_size = key_bits_size;
+
+ switch (tee_key_type) {
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ // Give enough room for generated keys in private format
+ max_object_size = key_bits_size * 8;
+ break;
+ }
- ret = TEE_AllocateTransientObject(tee_key_type, key_bits_size, dstHndl);
+ ret = TEE_AllocateTransientObject(tee_key_type, max_object_size, dstHndl);
if (TEE_SUCCESS != ret) {
LOG("TEE_AllocateTransientObject has failed with=%x. Arguments=(tee_key_type=%X, "
"key_bits_size=%d.", ret, tee_key_type, key_bits_size);
return ret;
}
-static TEE_Result KM_GetAttribute(TEE_ObjectHandle keyHndl, uint32_t attrId, KM_BinaryData *attr)
+static TEE_Result KM_GetValueAttribute(TEE_ObjectHandle keyHndl, uint32_t attrId, KM_BinaryData *attr)
+{
+ TEE_Result ret;
+ uint32_t a, b;
+
+ if (attr == NULL) {
+ LOG("Attribute buffer is NULL");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ if (!isValueAttr(attrId)) {
+ LOG("attributeID is not for value. attrId=%x", attrId);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ attr->data_size = sizeof(uint32_t) * 2; // for a and b of TEE_Attribute.content.value
+ attr->data = malloc(attr->data_size);
+ if (attr->data == NULL) {
+ LOG("Failed to allocate memory for key attribute.");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
+ ret = TEE_GetObjectValueAttribute(keyHndl, attrId, &a, &b);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to get object value attribute info, ret = %x", ret);
+ goto clean;
+ }
+ memcpy(attr->data, &a, sizeof(uint32_t));
+ memcpy((attr->data) + sizeof(uint32_t), &b, sizeof(uint32_t));
+
+clean:
+ if (ret != TEE_SUCCESS) {
+ free(attr->data);
+ attr->data = NULL;
+ attr->data_size = 0;
+ }
+ return ret;
+}
+
+static TEE_Result KM_GetBufferAttribute(TEE_ObjectHandle keyHndl, uint32_t attrId, KM_BinaryData *attr)
{
TEE_ObjectInfo objInfo;
TEE_Result ret;
return TEE_ERROR_BAD_PARAMETERS;
}
+ if (isValueAttr(attrId)) {
+ LOG("attributeID is not for buffer. attrId=%x", attrId);
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
/*
* TODO current key size is used as maximum attribute size because prompting the size with NULL
* buffer in TEE_GetObjectBufferAttribute doesn't work in simulator.
return ret;
}
+static TEE_Result KM_GetAttribute(TEE_ObjectHandle keyHndl, uint32_t attrId, KM_BinaryData *attr)
+{
+ if (isValueAttr(attrId))
+ return KM_GetValueAttribute(keyHndl, attrId, attr);
+ else
+ return KM_GetBufferAttribute(keyHndl, attrId, attr);
+}
+
static TEE_Result KM_EncryptAsymKeyInternal(TEE_ObjectHandle keyHndl, const KM_PwdData *pwd,
const uint32_t *attrIds, const uint32_t attrsCount,
KM_BinaryData *encKey, KM_BinaryData *tag)
TEE_Attribute attributes[attrsCount];
uint32_t i = 0;
uint32_t maxObjectSizeBits = 0;
+ uint32_t *a, *b;
if (KM_DeserializeFlag(&data, &dataSize, &maxObjectSizeBits)) {
LOG("Failed to deserialize object size");
return TEE_ERROR_BAD_PARAMETERS;
}
- KM_InitRefAttribute(&attributes[i], attrIDs[i], readAttr[i].data, readAttr[i].data_size);
+ if (isValueAttr(attrIDs[i])) {
+ a = readAttr[i].data;
+ b = readAttr[i].data + sizeof(uint32_t);
+ KM_InitValueAttribute(&attributes[i], attrIDs[i], *a, *b);
+ } else {
+ KM_InitRefAttribute(&attributes[i], attrIDs[i], readAttr[i].data, readAttr[i].data_size);
+ }
}
return KM_CreateTransientObject(keyType, maxObjectSizeBits, attributes, attrsCount, hndl);
return KM_EncryptAsymKeyInternal(keyHndl, pwd,
DSA_PUBLIC_ATTRIBUTES, DSA_PUBLIC_ATTRIBUTES_SIZE,
encKey, tag);
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ return KM_EncryptAsymKeyInternal(keyHndl, pwd,
+ ECC_PRIVATE_ATTRIBUTES, ECC_PRIVATE_ATTRIBUTES_SIZE,
+ encKey, tag);
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_PUBLIC_KEY:
+ return KM_EncryptAsymKeyInternal(keyHndl, pwd,
+ ECC_PUBLIC_ATTRIBUTES, ECC_PUBLIC_ATTRIBUTES_SIZE,
+ encKey, tag);
default:
LOG("Invalid object type provided for asymmetric key encryption");
return TEE_ERROR_BAD_PARAMETERS;
ret = KM_CreateDecryptedAsymKey(bufferPtr, bufferSizeGuard, keyType,
DSA_PUBLIC_ATTRIBUTES, DSA_PUBLIC_ATTRIBUTES_SIZE, decKeyHndl);
break;
+ case TEE_TYPE_ECDSA_KEYPAIR:
+ case TEE_TYPE_ECDH_KEYPAIR:
+ ret = KM_CreateDecryptedAsymKey(bufferPtr, bufferSizeGuard, keyType,
+ ECC_PRIVATE_ATTRIBUTES, ECC_PRIVATE_ATTRIBUTES_SIZE, decKeyHndl);
+ break;
+ case TEE_TYPE_ECDSA_PUBLIC_KEY:
+ case TEE_TYPE_ECDH_PUBLIC_KEY:
+ ret = KM_CreateDecryptedAsymKey(bufferPtr, bufferSizeGuard, keyType,
+ ECC_PUBLIC_ATTRIBUTES, ECC_PUBLIC_ATTRIBUTES_SIZE, decKeyHndl);
+ break;
default:
LOG("Invalid object type provided for decrypted key creation");
ret = TEE_ERROR_BAD_PARAMETERS;
TEE_GetObjectInfo(op_key_hndl, &info);
bits = KM_ObjectSizeBits(&info);
- LOGD("Operation key size: %d alg: %x", bits, algo);
+ LOGD("Operation key size: %d alg: %x mode: %x", bits, algo, mode);
ret = TEE_AllocateOperation(hndl, algo, mode, bits);
if (TEE_SUCCESS != ret) {
LOG("TEE_AllocateOperation has failed with=%x.", ret);