static int sign_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params, const uint8_t* data, const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) { if (sign_params->digest_type != DIGEST_NONE) { ALOGW("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGW("Cannot handle padding type %d", sign_params->padding_type); return -1; } Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey)); if (rsa.get() == NULL) { logOpenSSLError("openssl_sign_rsa"); return -1; } UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength))); if (signedDataPtr.get() == NULL) { logOpenSSLError("openssl_sign_rsa"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get()); if (RSA_private_encrypt(dataLength, data, tmp, rsa.get(), RSA_NO_PADDING) <= 0) { logOpenSSLError("openssl_sign_rsa"); return -1; } *signedDataLength = dataLength; *signedData = signedDataPtr.release(); return 0; }
static int sign_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params, const uint8_t* data, const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) { if (sign_params->digest_type != DIGEST_NONE) { ALOGW("Cannot handle digest type %d", sign_params->digest_type); return -1; } Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey)); if (eckey.get() == NULL) { logOpenSSLError("openssl_sign_ec"); return -1; } unsigned int ecdsaSize = ECDSA_size(eckey.get()); UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize))); if (signedDataPtr.get() == NULL) { logOpenSSLError("openssl_sign_ec"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get()); if (ECDSA_sign(0, data, dataLength, tmp, &ecdsaSize, eckey.get()) <= 0) { logOpenSSLError("openssl_sign_ec"); return -1; } *signedDataLength = ecdsaSize; *signedData = signedDataPtr.release(); return 0; }
static int openssl_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) { int result = -1; EVP_MD_CTX ctx; size_t maxSize; if (data == NULL) { ALOGW("input data to sign == NULL"); return -1; } else if (signedData == NULL || signedDataLength == NULL) { ALOGW("output signature buffer == NULL"); return -1; } Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength)); if (pkey.get() == NULL) { return -1; } if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { ALOGW("Cannot handle non-RSA keys yet"); return -1; } keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params; if (sign_params->digest_type != DIGEST_NONE) { ALOGW("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGW("Cannot handle padding type %d", sign_params->padding_type); return -1; } Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get())); if (rsa.get() == NULL) { logOpenSSLError("openssl_sign_data"); return -1; } UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength))); if (signedDataPtr.get() == NULL) { logOpenSSLError("openssl_sign_data"); return -1; } unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get()); if (RSA_private_encrypt(dataLength, data, tmp, rsa.get(), RSA_NO_PADDING) <= 0) { logOpenSSLError("openssl_sign_data"); return -1; } *signedDataLength = dataLength; *signedData = signedDataPtr.release(); return 0; }
static int qcom_km_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) { if (dev->context == NULL) { ALOGE("qcom_km_sign_data: Context == NULL"); return -1; } if (dataLength > KM_KEY_SIZE_MAX) { ALOGE("Input data to be signed is too long %d bytes", dataLength); return -1; } if (data == NULL) { ALOGE("input data to sign == NULL"); return -1; } else if (signedData == NULL || signedDataLength == NULL) { ALOGE("Output signature buffer == NULL"); return -1; } keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params; if (sign_params->digest_type != DIGEST_NONE) { ALOGE("Cannot handle digest type %d", sign_params->digest_type); return -1; } else if (sign_params->padding_type != PADDING_NONE) { ALOGE("Cannot handle padding type %d", sign_params->padding_type); return -1; } struct QSEECom_handle *handle = NULL; keymaster_sign_data_cmd_t *send_cmd = NULL; keymaster_sign_data_resp_t *resp = NULL; struct QSEECom_ion_fd_info ion_fd_info; struct qcom_km_ion_info_t ihandle; struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context; int ret = 0; handle = (struct QSEECom_handle *)(km_handle->qseecom); ihandle.ion_fd = 0; ihandle.ion_alloc_handle.handle = NULL; if (qcom_km_ION_memalloc(&ihandle, dataLength) < 0) { ALOGE("ION allocation failed"); return -1; } memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info)); /* Populate the send data structure */ ion_fd_info.data[0].fd = ihandle.ifd_data_fd; ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) + sizeof(qcom_km_key_blob_t) + sizeof(keymaster_rsa_sign_params_t); send_cmd = (keymaster_sign_data_cmd_t *)handle->ion_sbuffer; resp = (keymaster_sign_data_resp_t *)(handle->ion_sbuffer + QSEECOM_ALIGN(sizeof(keymaster_sign_data_cmd_t))); send_cmd->cmd_id = KEYMASTER_SIGN_DATA ; send_cmd->sign_param.digest_type = sign_params->digest_type; send_cmd->sign_param.padding_type = sign_params->padding_type; memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength); memcpy((unsigned char *)ihandle.ion_sbuffer, data, dataLength); send_cmd->data = (uint32_t)ihandle.ion_sbuffer; send_cmd->dlen = dataLength; resp->sig_len = KM_KEY_SIZE_MAX; resp->status = KEYMASTER_FAILURE; ret = (*km_handle->QSEECom_set_bandwidth)(handle, true); if (ret < 0) { ALOGE("Sign data command failed (unable to enable clks) ret =%d", ret); qcom_km_ion_dealloc(&ihandle); return -1; } ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd, QSEECOM_ALIGN(sizeof(*send_cmd)), resp, QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info); if((*km_handle->QSEECom_set_bandwidth)(handle, false)) ALOGE("Sign data command: (unable to disable clks)"); if ( (ret < 0) || (resp->status < 0)) { ALOGE("Sign data command failed resp->status = %d ret =%d", resp->status, ret); qcom_km_ion_dealloc(&ihandle); return -1; } else { UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(resp->sig_len))); if (signedDataPtr.get() == NULL) { ALOGE("Sign data memory allocation failed"); qcom_km_ion_dealloc(&ihandle); return -1; } unsigned char* p = signedDataPtr.get(); memcpy(p, (unsigned char *)(&resp->signed_data), resp->sig_len); *signedDataLength = resp->sig_len; *signedData = signedDataPtr.release(); } qcom_km_ion_dealloc(&ihandle); return 0; }