Home | History | Annotate | Download | only in trusty
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "TrustyKeymaster"
     18 
     19 // TODO: make this generic in libtrusty
     20 
     21 #include <assert.h>
     22 #include <errno.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <unistd.h>
     26 
     27 #include <log/log.h>
     28 
     29 #include "keymaster_ipc.h"
     30 #include "trusty_keymaster_ipc.h"
     31 #include "qemud.h"
     32 
     33 #define KEYMASTER_SERVICE_NAME "KeymasterService3"
     34 
     35 static int handle_ = 0;
     36 
     37 int trusty_keymaster_connect() {
     38     ALOGE("calling %s\n", __func__);
     39     handle_ = qemu_pipe_open(KEYMASTER_SERVICE_NAME);
     40     if (handle_ < 0) {
     41         handle_ = 0;
     42         ALOGE("failed to open %s pipe service", KEYMASTER_SERVICE_NAME);
     43         ALOGE("calling %s failed\n", __func__);
     44         return -1;
     45     }
     46     ALOGE("calling %s succeeded\n", __func__);
     47     return 0;
     48 }
     49 
     50 int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out,
     51                           uint32_t* out_size) {
     52 
     53     size_t msg_size = in_size + sizeof(struct keymaster_message);
     54     ALOGE("calling %s insize %d msg size %d\n", __func__, (int)in_size, (int) msg_size);
     55     struct keymaster_message* msg = reinterpret_cast<struct keymaster_message*>(malloc(msg_size));
     56     msg->cmd = cmd;
     57     memcpy(msg->payload, in, in_size);
     58 
     59     int pipe_command_length = msg_size;
     60     assert(pipe_command_length > 0);
     61     ssize_t rc = WriteFully(handle_, &pipe_command_length, sizeof(pipe_command_length));
     62     if (rc < 1) {
     63         ALOGE("failed to send msg_size (%d) for cmd (%d) to %s: %s\n", (int)(sizeof(pipe_command_length)),
     64                 (int)cmd, KEYMASTER_PORT, strerror(errno));
     65         return -errno;
     66     }
     67 
     68     rc = WriteFully(handle_, msg, pipe_command_length);
     69     if (in_size == 157 && cmd == KM_FINISH_OPERATION) {
     70         for (int i=0; i < (int)in_size; ++i) {
     71             ALOGE("pay[%d]: %d", i, (int)(msg->payload[i]));
     72         }
     73     }
     74     free(msg);
     75 
     76 
     77     if (rc < 1) {
     78         ALOGE("failed to send cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, strerror(errno));
     79         return -errno;
     80     }
     81 
     82     rc = ReadFully(handle_, &pipe_command_length, sizeof(pipe_command_length));
     83     if (rc < 1) {
     84         ALOGE("failed to retrieve response length for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT,
     85               strerror(errno));
     86         return -errno;
     87     }
     88 
     89     rc = ReadFully(handle_, out, pipe_command_length);
     90     if (rc < 1) {
     91         ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT,
     92               strerror(errno));
     93         return -errno;
     94     }
     95     *out_size = pipe_command_length;
     96     return pipe_command_length;
     97 }
     98 
     99 void trusty_keymaster_disconnect() {
    100     ALOGE("calling %s\n", __func__);
    101     if (handle_ != 0) {
    102         close(handle_);
    103         handle_ = 0;
    104     }
    105 }
    106