132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler/* 232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * Copyright (C) 2016 The Android Open Source Project 332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * 432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * Licensed under the Apache License, Version 2.0 (the "License"); 532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * you may not use this file except in compliance with the License. 632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * You may obtain a copy of the License at 732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * 832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * http://www.apache.org/licenses/LICENSE-2.0 932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * 1032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * Unless required by applicable law or agreed to in writing, software 1132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * distributed under the License is distributed on an "AS IS" BASIS, 1232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * See the License for the specific language governing permissions and 1432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler * limitations under the License. 1532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler */ 1632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 17ff2dcd9af994a23ed483939a416b48bdc10eefd5Mark Salyzyn#define LOG_TAG "TrustyNVRAM" 18ff2dcd9af994a23ed483939a416b48bdc10eefd5Mark Salyzyn 19ab8fe428db9503a623e946a55cbf7b3605dc5658Mattias Nissler#include "trusty_nvram_implementation.h" 20ab8fe428db9503a623e946a55cbf7b3605dc5658Mattias Nissler 2132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler#include <errno.h> 2232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler#include <string.h> 23cfd5b080af8de527d768f0ff7902c26af8d49307Mark Salyzyn#include <unistd.h> 2432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 2532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler#include <hardware/nvram.h> 2630f991f251940be3ed11566fb71139852286f68aMark Salyzyn#include <log/log.h> 2732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler#include <trusty/tipc.h> 2832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 2932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler#include <nvram/messages/blob.h> 3032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 31ab8fe428db9503a623e946a55cbf7b3605dc5658Mattias Nisslernamespace nvram { 3232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nisslernamespace { 3332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 3432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler// Character device to open for Trusty IPC connections. 3532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nisslerconst char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0"; 3632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 3732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler// App identifier of the NVRAM app. 3832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nisslerconst char kTrustyNvramAppId[] = "com.android.trusty.nvram"; 3932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 40ab8fe428db9503a623e946a55cbf7b3605dc5658Mattias Nissler} // namespace 4132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 4232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias NisslerTrustyNvramImplementation::~TrustyNvramImplementation() { 4332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (tipc_nvram_fd_ != -1) { 4432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler tipc_close(tipc_nvram_fd_); 4532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler tipc_nvram_fd_ = -1; 4632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 4732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler} 4832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 4932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nisslervoid TrustyNvramImplementation::Execute(const nvram::Request& request, 5032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler nvram::Response* response) { 5132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (!SendRequest(request, response)) { 5232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler response->result = NV_RESULT_INTERNAL_ERROR; 5332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 5432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler} 5532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 5632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nisslerbool TrustyNvramImplementation::Connect() { 5732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (tipc_nvram_fd_ != -1) { 5832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return true; 5932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 6032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 6132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler int rc = tipc_connect(kTrustyDeviceName, kTrustyNvramAppId); 6232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (rc < 0) { 6332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("Failed to connect to Trusty NVRAM app: %s\n", strerror(-rc)); 6432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 6532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 6632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 6732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler tipc_nvram_fd_ = rc; 6832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return true; 6932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler} 7032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 7132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nisslerbool TrustyNvramImplementation::SendRequest(const nvram::Request& request, 7232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler nvram::Response* response) { 7332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (!Connect()) { 7432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 7532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 7632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 7732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler nvram::Blob request_buffer; 7832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (!nvram::Encode(request, &request_buffer)) { 7932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("Failed to encode NVRAM request.\n"); 8032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 8132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 8232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 8332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ssize_t rc = 8432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler write(tipc_nvram_fd_, request_buffer.data(), request_buffer.size()); 8532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (rc < 0) { 8632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("Failed to send NVRAM request: %s\n", strerror(-rc)); 8732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 8832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 8932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (static_cast<size_t>(rc) != request_buffer.size()) { 9032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("Failed to send full request buffer: %zd\n", rc); 9132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 9232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 9332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 9432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler rc = read(tipc_nvram_fd_, response_buffer_, sizeof(response_buffer_)); 9532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (rc < 0) { 9632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("Failed to read NVRAM response: %s\n", strerror(-rc)); 9732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 9832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 9932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 10032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (static_cast<size_t>(rc) >= sizeof(response_buffer_)) { 10132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("NVRAM response exceeds response buffer size.\n"); 10232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 10332ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 10432ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 10532ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler if (!nvram::Decode(response_buffer_, static_cast<size_t>(rc), response)) { 10632ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler ALOGE("Failed to decode NVRAM response.\n"); 10732ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return false; 10832ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler } 10932ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 11032ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler return true; 11132ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler} 11232ac6aafa41b20db7acd1257c32c731ae3dd7aa5Mattias Nissler 113ab8fe428db9503a623e946a55cbf7b3605dc5658Mattias Nissler} // namespace nvram 114