/******************************************** KeyMaster OEM API ALLWINNER TECH.CO version 1.0 by wanglford 20170227 ********************************************* The Keymaster APIs achieve 5 functions ********************************************* */ #define LOG_NDEBUG 0 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "include/keymaster_errno.h" #include "include/keymaster_def.h" #include typedef keymaster0_device_t keymaster_device_t; typedef UniquePtr Unique_keymaster_device_t; enum { /*keep in sync with definition in secure os*/ MSG_KEYMASTER_MIN = 0x200, MSG_KEYMASTER_INITIALIZE, MSG_KEYMASTER_TERMINATE, MSG_KEYMASTER_GENERATE_KEYPARIS, MSG_KEYMASTER_IMPORT_KEYPARIS, MSG_KEYMASTER_GET_KEYPARIS_PUBLIC,//5 MSG_KEYMASTER_SIGN_DATA, MSG_KEYMASTER_VERIFY_DATA, MSG_KEYMASTER_MAX, }; //UUID for keymaster static const uint8_t KeyMasterUUID[16] = { 0x60,0xbe,0xbe,0xd6,0x3e,0xbe,0x46,0x40, 0xb2,0x39,0x89,0x1e,0x0a,0x59,0x48,0x60 }; static pthread_mutex_t gKeyMasterMutex = PTHREAD_MUTEX_INITIALIZER; static TEEC_Context *gKeyMasterContext = NULL; static TEEC_Session *gKeyMasterSession = NULL; #if 0 void hexdump(unsigned char * data, int size) { int i = 0; int line ; char tmp[32 + 16 + 11 + 1]; int offset = 0; for(line = 0; offset < size; line ++ ) { sprintf(&tmp[0], "0x%08x:", line*16); if(size - offset >= 16) { for(i = 0; i < 16; i++) { sprintf(&tmp[(i + 1) * 3 + 8], "%02x ", data[offset + i]); } offset += 16; } else { for(i = 0; i < size - offset; i++) { sprintf(&tmp[(i + 1) * 3 + 8], "%02x ", data[offset + i]); } offset = size; } tmp[32 + 16 + 11] = '\0'; ALOGD("%s", tmp); } } #endif int KeyMaster_Initialize(void) { //ALOGD("KeyMaster_Initialize"); pthread_mutex_lock(&gKeyMasterMutex); if (gKeyMasterContext != NULL) { pthread_mutex_unlock(&gKeyMasterMutex); return 0; } gKeyMasterContext = (TEEC_Context *)malloc(sizeof(TEEC_Context)); gKeyMasterSession = (TEEC_Session *)malloc(sizeof(TEEC_Session)); assert(gKeyMasterContext != NULL); assert(gKeyMasterSession != NULL); pthread_mutex_unlock(&gKeyMasterMutex); TEEC_Result success = TEEC_InitializeContext(NULL, gKeyMasterContext); if (success != TEEC_SUCCESS) { ALOGE("initialize context failed"); return -1; } success = TEEC_OpenSession(gKeyMasterContext, gKeyMasterSession, (const TEEC_UUID *)&KeyMasterUUID[0], TEEC_LOGIN_PUBLIC, NULL, NULL, NULL); if (success != TEEC_SUCCESS) { ALOGE("open session failed"); return -1; } TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.started = 1; success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_INITIALIZE, &operation, NULL); return (int) success; } int KeyMaster_Terminate(void) { //ALOGD("KeyMaster_Terminate"); pthread_mutex_lock(&gKeyMasterMutex); if (gKeyMasterContext == NULL) { pthread_mutex_unlock(&gKeyMasterMutex); return 0; } TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.started = 1; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_TERMINATE, &operation, NULL); if (success != TEEC_SUCCESS) { ALOGE("call invoke command error"); } TEEC_CloseSession(gKeyMasterSession); TEEC_FinalizeContext(gKeyMasterContext); free(gKeyMasterSession); free(gKeyMasterContext); gKeyMasterSession = NULL; gKeyMasterContext = NULL; pthread_mutex_unlock(&gKeyMasterMutex); return (int) success; } static int __generate_rsa_key ( const keymaster_keypair_t key_type, const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength) { TEEC_SharedMemory key_p; key_p.size = sizeof(keymaster_rsa_keygen_params_t); key_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_p) != TEEC_SUCCESS) { ALOGE("%s: allocate key parameters share memory fail", __func__); return -1; } memcpy(key_p.buffer, key_params, sizeof(keymaster_rsa_keygen_params_t)); TEEC_SharedMemory outputMem; outputMem.size = AW_KEYMASTER_BLOB_SIZE; outputMem.flags = TEEC_MEM_OUTPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &outputMem) != TEEC_SUCCESS) { ALOGE("%s: __generate_rsa_key: allocate key output share memory fail", __func__); TEEC_ReleaseSharedMemory(&key_p); return -1; } TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE); operation.started = 1; operation.params[0].value.a = key_type; operation.params[1].memref.parent = &key_p; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; operation.params[2].memref.parent = &outputMem; operation.params[2].memref.offset = 0; operation.params[2].memref.size = 0; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_GENERATE_KEYPARIS, &operation, NULL); //ALOGE("%s %d %d\n", __func__, __LINE__, success); if (!success) { uint8_t *keyblob_buf = new uint8_t[operation.params[2].memref.size]; *keyBlobLength = operation.params[2].memref.size; memcpy(keyblob_buf, outputMem.buffer, *keyBlobLength); *keyBlob = keyblob_buf; } //ALOGE("%s %d %d\n", __func__, __LINE__, *keyBlobLength); TEEC_ReleaseSharedMemory(&key_p); TEEC_ReleaseSharedMemory(&outputMem); return (int) success; } static int __generate_ec_key ( const keymaster_keypair_t key_type, const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength ) { //keymaster_ec_keygen_params_t *params = (keymaster_ec_keygen_params_t *)key_params; TEEC_SharedMemory key_p; key_p.size = sizeof(keymaster_ec_keygen_params_t); key_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_p) != TEEC_SUCCESS) { ALOGE("%s: allocate key parameters share memory fail", __func__); return -1; } memcpy(key_p.buffer, key_params, sizeof(keymaster_ec_keygen_params_t)); TEEC_SharedMemory outputMem; outputMem.size = AW_KEYMASTER_BLOB_SIZE; outputMem.flags = TEEC_MEM_OUTPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &outputMem) != TEEC_SUCCESS) { ALOGE("%s: allocate key output share memory fail", __func__); TEEC_ReleaseSharedMemory(&key_p); return -1; } TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE); operation.started = 1; operation.params[0].value.a = key_type; operation.params[1].memref.parent = &key_p; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; operation.params[2].memref.parent = &outputMem; operation.params[2].memref.offset = 0; operation.params[2].memref.size = 0; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_GENERATE_KEYPARIS, &operation, NULL); //ALOGE("%s %d %d\n", __func__, __LINE__, success); if (!success) { uint8_t *keyblob_buf = new uint8_t[operation.params[2].memref.size]; *keyBlobLength = operation.params[2].memref.size; memcpy(keyblob_buf, outputMem.buffer, *keyBlobLength); *keyBlob = keyblob_buf; } //ALOGE("%s %d %d\n", __func__, __LINE__, *keyBlobLength); //ALOGE("%s %d %d\n", __func__, __LINE__, sizeof(aw_key_blob_format_t)); TEEC_ReleaseSharedMemory(&outputMem); TEEC_ReleaseSharedMemory(&key_p); return (int) success; } static int __generate_dsa_key ( const keymaster_keypair_t key_type, const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength ) { const keymaster_dsa_keygen_params_t* dsa_params = (const keymaster_dsa_keygen_params_t*) key_params; keymaster_dsa_keygen_params_t *dsa_key_p; int success; int alloc_flag = 0; if ((dsa_params->generator == NULL ) || (dsa_params->prime_p == NULL ) || (dsa_params->prime_q == NULL )) { ALOGE("%s: dsa params pointer is NULL\n", __func__); return -1; } if ((dsa_params->generator_len == 0 ) || (dsa_params->prime_p_len == 0 ) || (dsa_params->prime_q_len == 0 )) { ALOGE("%s: dsa params size is NULL\n", __func__); return -1; } TEEC_SharedMemory key_p; key_p.size = sizeof(keymaster_dsa_keygen_params_t); key_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_p) != TEEC_SUCCESS) { ALOGE("%s: allocate key parameters share memory fail", __func__); success = -1; goto __generate_dsa_key_exit; } dsa_key_p = (keymaster_dsa_keygen_params_t *)key_p.buffer; alloc_flag |= (1<<0); TEEC_SharedMemory generator; generator.size = dsa_params->generator_len; generator.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &generator) != TEEC_SUCCESS) { ALOGE("%s: allocate dsa key generator share memory fail", __func__); success = -1; goto __generate_dsa_key_exit; } alloc_flag |= (1<<1); TEEC_SharedMemory prime_p; prime_p.size = dsa_params->prime_p_len; prime_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &prime_p) != TEEC_SUCCESS) { ALOGE("%s: allocate dsa key prime_p share memory fail", __func__); success = -1; goto __generate_dsa_key_exit; } alloc_flag |= (1<<2); TEEC_SharedMemory prime_q; prime_q.size = dsa_params->prime_q_len; prime_q.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &prime_q) != TEEC_SUCCESS) { ALOGE("%s: allocate dsa key prime_q share memory fail", __func__); success = -1; goto __generate_dsa_key_exit; } alloc_flag |= (1<<3); memcpy(generator.buffer, dsa_params->generator, dsa_params->generator_len); memcpy(prime_p.buffer, dsa_params->prime_p, dsa_params->prime_p_len); memcpy(prime_q.buffer, dsa_params->prime_q, dsa_params->prime_q_len); dsa_key_p->generator = (const uint8_t *)generator.buffer; dsa_key_p->prime_p = (const uint8_t *)prime_p.buffer; dsa_key_p->prime_q = (const uint8_t *)prime_q.buffer; dsa_key_p->generator_len = generator.size; dsa_key_p->generator_len = prime_p.size; dsa_key_p->prime_q_len = prime_q.size; dsa_key_p->key_size = dsa_params->key_size; TEEC_SharedMemory outputMem; outputMem.size = AW_KEYMASTER_BLOB_SIZE; outputMem.flags = TEEC_MEM_OUTPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &outputMem) != TEEC_SUCCESS) { ALOGE("%s: allocate key output share memory fail", __func__); success = -1; goto __generate_dsa_key_exit; } alloc_flag |= (1<<4); TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE); operation.started = 1; operation.params[0].value.a = key_type; operation.params[1].memref.parent = &key_p; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; operation.params[2].memref.parent = &outputMem; operation.params[2].memref.offset = 0; operation.params[2].memref.size = 0; success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_GENERATE_KEYPARIS, &operation, NULL); //ALOGE("%s %d %d\n", __func__, __LINE__, success); if (!success) { uint8_t *keyblob_buf = new uint8_t[operation.params[2].memref.size]; *keyBlobLength = operation.params[2].memref.size; memcpy(keyblob_buf, outputMem.buffer, *keyBlobLength); *keyBlob = keyblob_buf; } else { ALOGE("success=%d\n", success); } __generate_dsa_key_exit: if (alloc_flag & (1<<0)) TEEC_ReleaseSharedMemory(&key_p); if (alloc_flag & (1<<1)) TEEC_ReleaseSharedMemory(&generator); if (alloc_flag & (1<<2)) TEEC_ReleaseSharedMemory(&prime_p); if (alloc_flag & (1<<3)) TEEC_ReleaseSharedMemory(&prime_q); if (alloc_flag & (1<<4)) TEEC_ReleaseSharedMemory(&outputMem); return success; } int KeyMaster_Generate_keypairs(const keymaster_device_t* dev, const keymaster_keypair_t key_type, const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength) { //ALOGD("KeyMaster_Generate_keypairs"); if (dev->context == NULL) { ALOGE("KeyMaster_Generate_keyparis: Context NULL Ptr Err!"); return -1; } if (key_params == NULL) { ALOGE("KeyMaster_Generate_keyparis: key_params NULL Ptr Err!, %d", __LINE__); return -1; } if (keyBlob == NULL || keyBlobLength == NULL) { ALOGE("KeyMaster_Generate_keyparis: output key blob or length == NULL"); return -1; } //ALOGD("%d %s\n", __LINE__, __func__); if (key_type == TYPE_DSA) { //ALOGD("%d %s\n", __LINE__, __func__); return __generate_dsa_key(key_type, key_params, keyBlob, keyBlobLength); } else if (key_type == TYPE_EC) { //ALOGD("%d %s\n", __LINE__, __func__); return __generate_ec_key(key_type, key_params, keyBlob, keyBlobLength); } else if (key_type == TYPE_RSA) { //ALOGD("%d %s\n", __LINE__, __func__); return __generate_rsa_key(key_type, key_params, keyBlob, keyBlobLength); } else { ALOGE("%s: unsupporte key type\n", __func__); return -1; } } int KeyMaster_Import_keyparis(const keymaster_device_t* dev, const uint8_t* key, const size_t key_length, uint8_t** keyBlob, size_t* key_blob_length) { //ALOGD("KeyMaster_Import_keyparis"); if (dev->context == NULL) { ALOGE("KeyMaster_Import_Keypairs: Context == NULL"); return -1; } if (key == NULL) { ALOGE("%s: Input key == NULL", __func__); return -1; } if (keyBlob == NULL || key_blob_length == NULL) { ALOGE("%s: Output key blob or length == NULL", __func__); return -1; } TEEC_SharedMemory key_p; key_p.size = key_length; key_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_p) != TEEC_SUCCESS) { ALOGE("%s: allocate key parameters share memory fail", __func__); return -1; } memcpy(key_p.buffer, key, key_length); TEEC_SharedMemory outputMem; outputMem.size = AW_KEYMASTER_BLOB_SIZE; outputMem.flags = TEEC_MEM_OUTPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &outputMem) != TEEC_SUCCESS) { ALOGE("%s: allocate key output share memory fail", __func__); TEEC_ReleaseSharedMemory(&key_p); return -1; } TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE); operation.started = 1; operation.params[0].memref.parent = &key_p; operation.params[0].memref.offset = 0; operation.params[0].memref.size = 0; operation.params[1].memref.parent = &outputMem; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_IMPORT_KEYPARIS, &operation, NULL); //ALOGE("key_blob_length = %d\n", operation.params[1].memref.size); if (!success) { uint8_t *keyblob_buf = new uint8_t[operation.params[1].memref.size]; *key_blob_length = operation.params[1].memref.size; memcpy(keyblob_buf, outputMem.buffer, *key_blob_length); *keyBlob = keyblob_buf; } //hexdump(*keyBlob, *key_blob_length); //ALOGE("*key_blob_length=%d\n", *key_blob_length); TEEC_ReleaseSharedMemory(&key_p); TEEC_ReleaseSharedMemory(&outputMem); return (int)success; } int KeyMaster_Get_keyparis_public ( const keymaster_device_t* dev, const uint8_t* keyBlob, const size_t key_blob_length, uint8_t** x509_data, size_t* x509_data_length) { //ALOGD("KeyMaster_Get_keyparis_public"); if (dev->context == NULL) { ALOGE("%s: Context == NULL", __func__); return -1; } if (x509_data == NULL || x509_data_length == NULL) { ALOGE("%s: Output public key buffer == NULL", __func__); return -1; } if (x509_data == NULL) { ALOGE("Supplied key blob was NULL"); return -1; } if ((keyBlob == NULL) || (key_blob_length ==0)) { ALOGE("%s: Supplied key blob was NULL", __func__); return -1; } //ALOGE("*key_blob_length=%d\n", key_blob_length); //hexdump((uint8_t*)keyBlob, key_blob_length); TEEC_SharedMemory outputMem; outputMem.size = AW_KEYMASTER_BLOB_SIZE; outputMem.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &outputMem) != TEEC_SUCCESS) { ALOGE("%s: allocate key input share memory fail", __func__); return -1; } memcpy(outputMem.buffer, keyBlob, key_blob_length); TEEC_SharedMemory key_p; key_p.size = 512; key_p.flags = TEEC_MEM_OUTPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_p) != TEEC_SUCCESS) { ALOGE("%s: allocate public key share memory fail", __func__); TEEC_ReleaseSharedMemory(&outputMem); return -1; } TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE); operation.started = 1; operation.params[0].memref.parent = &outputMem; operation.params[0].memref.offset = 0; operation.params[0].memref.size = 0; operation.params[1].memref.parent = &key_p; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_GET_KEYPARIS_PUBLIC, &operation, NULL); //ALOGE("%s %d %d\n", __func__, __LINE__, success); if (!success) { uint8_t *key = new uint8_t[operation.params[1].memref.size]; uint32_t key_length = operation.params[1].memref.size; memcpy(key, key_p.buffer, key_length); *x509_data = key; *x509_data_length = key_length; //hexdump((uint8_t*)key_p.buffer, key_length); } TEEC_ReleaseSharedMemory(&key_p); TEEC_ReleaseSharedMemory(&outputMem); //ALOGE("%s %d\n", __func__, __LINE__); //hexdump(NULL, *x509_data, *x509_data_length); return (int) success; } int KeyMaster_Sign_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob, const size_t keyBlobLength, const uint8_t* data, const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) { //ALOGD("KeyMaster_Sign_data"); if (dev->context == NULL) { ALOGE("%s: Context == NULL", __func__); return -1; } if (keyBlob == NULL) { ALOGE("%s blob == NULL", __func__); return -1; } if (keyBlobLength == 0) { ALOGE("%s keyBlobLength == 0", __func__); return -1; } if (data == NULL) { ALOGE("%s: input data to sign == NULL", __func__); return -1; } if (signedData == NULL || signedDataLength == NULL) { ALOGE("%s: Output signature buffer == NULL", __func__); return -1; } TEEC_SharedMemory key_lable; key_lable.size = keyBlobLength; key_lable.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_lable) != TEEC_SUCCESS) { ALOGE("%s: allocate key blob share memory fail", __func__); return -1; } memcpy(key_lable.buffer, keyBlob, keyBlobLength); TEEC_SharedMemory data_p; data_p.size = dataLength; data_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &data_p) != TEEC_SUCCESS) { ALOGE("%s: allocate data share memory fail", __func__); TEEC_ReleaseSharedMemory(&key_lable); return -1; } memcpy(data_p.buffer, data, dataLength); TEEC_SharedMemory sign_p; sign_p.size = 512; sign_p.flags = TEEC_MEM_OUTPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &sign_p) != TEEC_SUCCESS) { ALOGE("%s: allocate sign data share memory fail", __func__); TEEC_ReleaseSharedMemory(&data_p); TEEC_ReleaseSharedMemory(&key_lable); return -1; } TEEC_SharedMemory algo_para; algo_para.size = 32; algo_para.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &algo_para) != TEEC_SUCCESS) { ALOGE("%s: allocate key blob share memory fail", __func__); TEEC_ReleaseSharedMemory(&data_p); TEEC_ReleaseSharedMemory(&key_lable); TEEC_ReleaseSharedMemory(&sign_p); return -1; } memcpy(algo_para.buffer, params, 32); TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE); operation.started = 1; operation.params[0].memref.parent = &algo_para; operation.params[0].memref.offset = 0; operation.params[0].memref.size = 0; operation.params[1].memref.parent = &key_lable; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; operation.params[2].memref.parent = &data_p; operation.params[2].memref.offset = 0; operation.params[2].memref.size = 0; operation.params[3].memref.parent = &sign_p; operation.params[3].memref.offset = 0; operation.params[3].memref.size = 0; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_SIGN_DATA, &operation, NULL); //ALOGE("%s %d %d\n", __func__, __LINE__, success); //ALOGE("sign data size = %d\n", operation.params[3].memref.size); if (!success) { uint8_t *signedData_buf = new uint8_t[operation.params[3].memref.size]; *signedDataLength = operation.params[3].memref.size; memcpy(signedData_buf, sign_p.buffer, *signedDataLength); *signedData = signedData_buf; } TEEC_ReleaseSharedMemory(&key_lable); TEEC_ReleaseSharedMemory(&data_p); TEEC_ReleaseSharedMemory(&sign_p); TEEC_ReleaseSharedMemory(&algo_para); return (int) success; } int KeyMaster_Verify_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob, const size_t keyBlobLength, const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature, const size_t signatureLength) { //ALOGD("KeyMaster_Verify_data"); if (dev->context == NULL) { ALOGE("%s: qcom_km_sign_data: Context == NULL", __func__); return -1; } if (keyBlob == NULL) { ALOGE("%s blob == NULL", __func__); return -1; } if (keyBlobLength == 0) { ALOGE("%s keyBlobLength == 0", __func__); return -1; } if (signedData == NULL || signature == NULL) { ALOGE("%s: data or signature buffers == NULL", __func__); return -1; } if ((signedDataLength == 0) || (signatureLength == 0)) { ALOGE("%s: data or signature length == 0", __func__); return -1; } keymaster_private_sign_params_t *private_para = (keymaster_private_sign_params_t *)params; if (private_para->digest_type != PADDING_NONE) { ALOGE("%s: digest type is NOT PADDING_NONE", __func__); return -1; } TEEC_SharedMemory key_lable; key_lable.size = keyBlobLength; key_lable.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &key_lable) != TEEC_SUCCESS) { ALOGE("%s: allocate key blob share memory fail", __func__); return -1; } memcpy(key_lable.buffer, keyBlob, keyBlobLength); TEEC_SharedMemory data_p; data_p.size = signedDataLength; data_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &data_p) != TEEC_SUCCESS) { ALOGE("%s: allocate data share memory fail", __func__); TEEC_ReleaseSharedMemory(&key_lable); return -1; } memcpy(data_p.buffer, signedData, signedDataLength); TEEC_SharedMemory sign_p; sign_p.size = signatureLength; sign_p.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &sign_p) != TEEC_SUCCESS) { ALOGE("%s: allocate sign data share memory fail", __func__); TEEC_ReleaseSharedMemory(&sign_p); TEEC_ReleaseSharedMemory(&key_lable); return -1; } memcpy(sign_p.buffer, signature, signatureLength); TEEC_SharedMemory algo_para; algo_para.size = 32; algo_para.flags = TEEC_MEM_INPUT; if (TEEC_AllocateSharedMemory(gKeyMasterContext, &algo_para) != TEEC_SUCCESS) { ALOGE("%s: allocate key blob share memory fail", __func__); TEEC_ReleaseSharedMemory(&data_p); TEEC_ReleaseSharedMemory(&key_lable); TEEC_ReleaseSharedMemory(&sign_p); return -1; } memcpy(algo_para.buffer, params, 32); TEEC_Operation operation; memset(&operation, 0, sizeof(TEEC_Operation)); operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE); operation.started = 1; operation.params[0].memref.parent = &algo_para; operation.params[0].memref.offset = 0; operation.params[0].memref.size = 0; operation.params[1].memref.parent = &key_lable; operation.params[1].memref.offset = 0; operation.params[1].memref.size = 0; operation.params[2].memref.parent = &data_p; operation.params[2].memref.offset = 0; operation.params[2].memref.size = 0; operation.params[3].memref.parent = &sign_p; operation.params[3].memref.offset = 0; operation.params[3].memref.size = 0; TEEC_Result success = TEEC_InvokeCommand(gKeyMasterSession, MSG_KEYMASTER_VERIFY_DATA, &operation, NULL); //ALOGE("%s %d %d\n", __func__, __LINE__, success); TEEC_ReleaseSharedMemory(&algo_para); TEEC_ReleaseSharedMemory(&key_lable); TEEC_ReleaseSharedMemory(&data_p); TEEC_ReleaseSharedMemory(&sign_p); return (int) success; } /* Close an opened aw schw instance */ static int sunxi_tee_keymaster_device_close(hw_device_t *dev) { KeyMaster_Terminate(); delete dev; return 0; } /* * Generic device handling */ static int sunxi_tee_keymaster_device_open(const hw_module_t* module, const char* name, hw_device_t** device) { if (strcmp(name, KEYSTORE_KEYMASTER) != 0) return -EINVAL; ALOGV("%s:: Enter AW tee keymaster\n",__func__); Unique_keymaster_device_t dev(new keymaster_device_t); if (dev.get() == NULL) return -ENOMEM; dev->context = (void *)AW_KEYMASTER_TEE_HAL; dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.version = 1; dev->common.module = (struct hw_module_t*) module; dev->common.close = sunxi_tee_keymaster_device_close; dev->flags = 0; dev->generate_keypair = KeyMaster_Generate_keypairs; dev->import_keypair = KeyMaster_Import_keyparis; dev->get_keypair_public = KeyMaster_Get_keyparis_public; dev->delete_keypair = NULL; dev->delete_all = NULL; dev->sign_data = KeyMaster_Sign_data; dev->verify_data = KeyMaster_Verify_data; *device = reinterpret_cast(dev.release()); KeyMaster_Initialize(); ALOGV("%s:AW keymaster open sucessfully!\n",__func__); return 0; } static struct hw_module_methods_t keystore_module_methods = { .open = sunxi_tee_keymaster_device_open, }; struct keystore_module HAL_MODULE_INFO_SYM __attribute__ ((visibility ("default"))) = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = KEYMASTER_MODULE_API_VERSION_0_2, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = KEYSTORE_HARDWARE_MODULE_ID, .name = "AllWinnerTech KeyMaster Tee HAL", .author = "The Android Open Source Project", .methods = &keystore_module_methods, .dso = 0, .reserved = {}, }, };