• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #include <errno.h>
18 #include <fcntl.h>
19 #include <scsi/sg.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <unistd.h>
28 
29 #include <linux/major.h>
30 #include <linux/mmc/ioctl.h>
31 
32 #include <hardware_legacy/power.h>
33 
34 #include "ipc.h"
35 #include "log.h"
36 #include "rpmb.h"
37 #include "storage.h"
38 
39 #define MMC_READ_MULTIPLE_BLOCK 18
40 #define MMC_WRITE_MULTIPLE_BLOCK 25
41 #define MMC_RELIABLE_WRITE_FLAG (1 << 31)
42 
43 #define MMC_RSP_PRESENT (1 << 0)
44 #define MMC_RSP_CRC (1 << 2)
45 #define MMC_RSP_OPCODE (1 << 4)
46 #define MMC_CMD_ADTC (1 << 5)
47 #define MMC_RSP_SPI_S1 (1 << 7)
48 #define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
49 #define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
50 
51 #define MMC_WRITE_FLAG_R 0
52 #define MMC_WRITE_FLAG_W 1
53 #define MMC_WRITE_FLAG_RELW (MMC_WRITE_FLAG_W | MMC_RELIABLE_WRITE_FLAG)
54 
55 #define MMC_BLOCK_SIZE 512
56 
57 /*
58  * There should be no timeout for security protocol ioctl call, so we choose a
59  * large number for timeout.
60  * 20000 millisecs == 20 seconds
61  */
62 #define TIMEOUT 20000
63 
64 /*
65  * The sg device driver that supports new interface has a major version number of "3".
66  * SG_GET_VERSION_NUM ioctl() will yield a number greater than or 30000.
67  */
68 #define RPMB_MIN_SG_VERSION_NUM 30000
69 
70 /*
71  * CDB format of SECURITY PROTOCOL IN/OUT commands
72  * (JEDEC Standard No. 220D, Page 264)
73  */
74 struct sec_proto_cdb {
75     /*
76      * OPERATION CODE = A2h for SECURITY PROTOCOL IN command,
77      * OPERATION CODE = B5h for SECURITY PROTOCOL OUT command.
78      */
79     uint8_t opcode;
80     /* SECURITY PROTOCOL = ECh (JEDEC Universal Flash Storage) */
81     uint8_t sec_proto;
82     /*
83      * The SECURITY PROTOCOL SPECIFIC field specifies the RPMB Protocol ID.
84      * CDB Byte 2 = 00h and CDB Byte 3 = 01h for RPMB Region 0.
85      */
86     uint8_t cdb_byte_2;
87     uint8_t cdb_byte_3;
88     /*
89      * Byte 4 and 5 are reserved.
90      */
91     uint8_t cdb_byte_4;
92     uint8_t cdb_byte_5;
93     /* ALLOCATION/TRANSFER LENGTH in big-endian */
94     uint32_t length;
95     /* Byte 9 is reserved. */
96     uint8_t cdb_byte_10;
97     /* CONTROL = 00h. */
98     uint8_t ctrl;
99 } __packed;
100 
101 static int rpmb_fd = -1;
102 static uint8_t read_buf[4096];
103 static enum dev_type dev_type = UNKNOWN_RPMB;
104 
105 static const char* UFS_WAKE_LOCK_NAME = "ufs_seq_wakelock";
106 
107 #ifdef RPMB_DEBUG
108 
print_buf(const char * prefix,const uint8_t * buf,size_t size)109 static void print_buf(const char* prefix, const uint8_t* buf, size_t size) {
110     size_t i;
111 
112     printf("%s @%p [%zu]", prefix, buf, size);
113     for (i = 0; i < size; i++) {
114         if (i && i % 32 == 0) printf("\n%*s", (int)strlen(prefix), "");
115         printf(" %02x", buf[i]);
116     }
117     printf("\n");
118     fflush(stdout);
119 }
120 
121 #endif
122 
set_sg_io_hdr(sg_io_hdr_t * io_hdrp,int dxfer_direction,unsigned char cmd_len,unsigned char mx_sb_len,unsigned int dxfer_len,void * dxferp,unsigned char * cmdp,void * sbp)123 static void set_sg_io_hdr(sg_io_hdr_t* io_hdrp, int dxfer_direction, unsigned char cmd_len,
124                           unsigned char mx_sb_len, unsigned int dxfer_len, void* dxferp,
125                           unsigned char* cmdp, void* sbp) {
126     memset(io_hdrp, 0, sizeof(sg_io_hdr_t));
127     io_hdrp->interface_id = 'S';
128     io_hdrp->dxfer_direction = dxfer_direction;
129     io_hdrp->cmd_len = cmd_len;
130     io_hdrp->mx_sb_len = mx_sb_len;
131     io_hdrp->dxfer_len = dxfer_len;
132     io_hdrp->dxferp = dxferp;
133     io_hdrp->cmdp = cmdp;
134     io_hdrp->sbp = sbp;
135     io_hdrp->timeout = TIMEOUT;
136 }
137 
send_mmc_rpmb_req(int mmc_fd,const struct storage_rpmb_send_req * req)138 static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req) {
139     struct {
140         struct mmc_ioc_multi_cmd multi;
141         struct mmc_ioc_cmd cmd_buf[3];
142     } mmc = {};
143     struct mmc_ioc_cmd* cmd = mmc.multi.cmds;
144     int rc;
145 
146     const uint8_t* write_buf = req->payload;
147     if (req->reliable_write_size) {
148         cmd->write_flag = MMC_WRITE_FLAG_RELW;
149         cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK;
150         cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
151         cmd->blksz = MMC_BLOCK_SIZE;
152         cmd->blocks = req->reliable_write_size / MMC_BLOCK_SIZE;
153         mmc_ioc_cmd_set_data((*cmd), write_buf);
154 #ifdef RPMB_DEBUG
155         ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag);
156         print_buf("request: ", write_buf, req->reliable_write_size);
157 #endif
158         write_buf += req->reliable_write_size;
159         mmc.multi.num_of_cmds++;
160         cmd++;
161     }
162 
163     if (req->write_size) {
164         cmd->write_flag = MMC_WRITE_FLAG_W;
165         cmd->opcode = MMC_WRITE_MULTIPLE_BLOCK;
166         cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
167         cmd->blksz = MMC_BLOCK_SIZE;
168         cmd->blocks = req->write_size / MMC_BLOCK_SIZE;
169         mmc_ioc_cmd_set_data((*cmd), write_buf);
170 #ifdef RPMB_DEBUG
171         ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag);
172         print_buf("request: ", write_buf, req->write_size);
173 #endif
174         write_buf += req->write_size;
175         mmc.multi.num_of_cmds++;
176         cmd++;
177     }
178 
179     if (req->read_size) {
180         cmd->write_flag = MMC_WRITE_FLAG_R;
181         cmd->opcode = MMC_READ_MULTIPLE_BLOCK;
182         cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC, cmd->blksz = MMC_BLOCK_SIZE;
183         cmd->blocks = req->read_size / MMC_BLOCK_SIZE;
184         mmc_ioc_cmd_set_data((*cmd), read_buf);
185 #ifdef RPMB_DEBUG
186         ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag);
187 #endif
188         mmc.multi.num_of_cmds++;
189         cmd++;
190     }
191 
192     rc = ioctl(mmc_fd, MMC_IOC_MULTI_CMD, &mmc.multi);
193     if (rc < 0) {
194         ALOGE("%s: mmc ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
195     }
196     return rc;
197 }
198 
send_ufs_rpmb_req(int sg_fd,const struct storage_rpmb_send_req * req)199 static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req) {
200     int rc;
201     int wl_rc;
202     const uint8_t* write_buf = req->payload;
203     /*
204      * Meaning of member values are stated on the definition of struct sec_proto_cdb.
205      */
206     struct sec_proto_cdb in_cdb = {0xA2, 0xEC, 0x00, 0x01, 0x00, 0x00, 0, 0x00, 0x00};
207     struct sec_proto_cdb out_cdb = {0xB5, 0xEC, 0x00, 0x01, 0x00, 0x00, 0, 0x00, 0x00};
208     unsigned char sense_buffer[32];
209 
210     wl_rc = acquire_wake_lock(PARTIAL_WAKE_LOCK, UFS_WAKE_LOCK_NAME);
211     if (wl_rc < 0) {
212         ALOGE("%s: failed to acquire wakelock: %d, %s\n", __func__, wl_rc, strerror(errno));
213         return wl_rc;
214     }
215 
216     if (req->reliable_write_size) {
217         /* Prepare SECURITY PROTOCOL OUT command. */
218         out_cdb.length = __builtin_bswap32(req->reliable_write_size);
219         sg_io_hdr_t io_hdr;
220         set_sg_io_hdr(&io_hdr, SG_DXFER_TO_DEV, sizeof(out_cdb), sizeof(sense_buffer),
221                       req->reliable_write_size, (void*)write_buf, (unsigned char*)&out_cdb,
222                       sense_buffer);
223         rc = ioctl(sg_fd, SG_IO, &io_hdr);
224         if (rc < 0) {
225             ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
226             goto err_op;
227         }
228         write_buf += req->reliable_write_size;
229     }
230 
231     if (req->write_size) {
232         /* Prepare SECURITY PROTOCOL OUT command. */
233         out_cdb.length = __builtin_bswap32(req->write_size);
234         sg_io_hdr_t io_hdr;
235         set_sg_io_hdr(&io_hdr, SG_DXFER_TO_DEV, sizeof(out_cdb), sizeof(sense_buffer),
236                       req->write_size, (void*)write_buf, (unsigned char*)&out_cdb, sense_buffer);
237         rc = ioctl(sg_fd, SG_IO, &io_hdr);
238         if (rc < 0) {
239             ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
240             goto err_op;
241         }
242         write_buf += req->write_size;
243     }
244 
245     if (req->read_size) {
246         /* Prepare SECURITY PROTOCOL IN command. */
247         in_cdb.length = __builtin_bswap32(req->read_size);
248         sg_io_hdr_t io_hdr;
249         set_sg_io_hdr(&io_hdr, SG_DXFER_FROM_DEV, sizeof(in_cdb), sizeof(sense_buffer),
250                       req->read_size, read_buf, (unsigned char*)&in_cdb, sense_buffer);
251         rc = ioctl(sg_fd, SG_IO, &io_hdr);
252         if (rc < 0) {
253             ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
254         }
255     }
256 
257 err_op:
258     wl_rc = release_wake_lock(UFS_WAKE_LOCK_NAME);
259     if (wl_rc < 0) {
260         ALOGE("%s: failed to release wakelock: %d, %s\n", __func__, wl_rc, strerror(errno));
261     }
262 
263     return rc;
264 }
265 
send_virt_rpmb_req(int rpmb_fd,void * read_buf,size_t read_size,const void * payload,size_t payload_size)266 static int send_virt_rpmb_req(int rpmb_fd, void* read_buf, size_t read_size, const void* payload,
267                               size_t payload_size) {
268     int rc;
269     uint16_t res_count = read_size / MMC_BLOCK_SIZE;
270     uint16_t cmd_count = payload_size / MMC_BLOCK_SIZE;
271     rc = write(rpmb_fd, &res_count, sizeof(res_count));
272     if (rc < 0) {
273         return rc;
274     }
275     rc = write(rpmb_fd, &cmd_count, sizeof(cmd_count));
276     if (rc < 0) {
277         return rc;
278     }
279     rc = write(rpmb_fd, payload, payload_size);
280     if (rc < 0) {
281         return rc;
282     }
283     rc = read(rpmb_fd, read_buf, read_size);
284     return rc;
285 }
286 
rpmb_send(struct storage_msg * msg,const void * r,size_t req_len)287 int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
288     int rc;
289     const struct storage_rpmb_send_req* req = r;
290 
291     if (req_len < sizeof(*req)) {
292         ALOGW("malformed rpmb request: invalid length (%zu < %zu)\n", req_len, sizeof(*req));
293         msg->result = STORAGE_ERR_NOT_VALID;
294         goto err_response;
295     }
296 
297     size_t expected_len = sizeof(*req) + req->reliable_write_size + req->write_size;
298     if (req_len != expected_len) {
299         ALOGW("malformed rpmb request: invalid length (%zu != %zu)\n", req_len, expected_len);
300         msg->result = STORAGE_ERR_NOT_VALID;
301         goto err_response;
302     }
303 
304     if ((req->reliable_write_size % MMC_BLOCK_SIZE) != 0) {
305         ALOGW("invalid reliable write size %u\n", req->reliable_write_size);
306         msg->result = STORAGE_ERR_NOT_VALID;
307         goto err_response;
308     }
309 
310     if ((req->write_size % MMC_BLOCK_SIZE) != 0) {
311         ALOGW("invalid write size %u\n", req->write_size);
312         msg->result = STORAGE_ERR_NOT_VALID;
313         goto err_response;
314     }
315 
316     if (req->read_size % MMC_BLOCK_SIZE != 0 || req->read_size > sizeof(read_buf)) {
317         ALOGE("%s: invalid read size %u\n", __func__, req->read_size);
318         msg->result = STORAGE_ERR_NOT_VALID;
319         goto err_response;
320     }
321 
322     if (dev_type == MMC_RPMB) {
323         rc = send_mmc_rpmb_req(rpmb_fd, req);
324         if (rc < 0) {
325             msg->result = STORAGE_ERR_GENERIC;
326             goto err_response;
327         }
328     } else if (dev_type == UFS_RPMB) {
329         rc = send_ufs_rpmb_req(rpmb_fd, req);
330         if (rc < 0) {
331             ALOGE("send_ufs_rpmb_req failed: %d, %s\n", rc, strerror(errno));
332             msg->result = STORAGE_ERR_GENERIC;
333             goto err_response;
334         }
335     } else if ((dev_type == VIRT_RPMB) || (dev_type == SOCK_RPMB)) {
336         size_t payload_size = req->reliable_write_size + req->write_size;
337         rc = send_virt_rpmb_req(rpmb_fd, read_buf, req->read_size, req->payload, payload_size);
338         if (rc < 0) {
339             ALOGE("send_virt_rpmb_req failed: %d, %s\n", rc, strerror(errno));
340             msg->result = STORAGE_ERR_GENERIC;
341             goto err_response;
342         }
343         if (rc != req->read_size) {
344             ALOGE("send_virt_rpmb_req got incomplete response: "
345                   "(size %d, expected %d)\n",
346                   rc, req->read_size);
347             msg->result = STORAGE_ERR_GENERIC;
348             goto err_response;
349         }
350     } else {
351         ALOGE("Unsupported dev_type\n");
352         msg->result = STORAGE_ERR_GENERIC;
353         goto err_response;
354     }
355 #ifdef RPMB_DEBUG
356     if (req->read_size) print_buf("response: ", read_buf, req->read_size);
357 #endif
358 
359     if (msg->flags & STORAGE_MSG_FLAG_POST_COMMIT) {
360         /*
361          * Nothing todo for post msg commit request as MMC_IOC_MULTI_CMD
362          * is fully synchronous in this implementation.
363          */
364     }
365 
366     msg->result = STORAGE_NO_ERROR;
367     return ipc_respond(msg, read_buf, req->read_size);
368 
369 err_response:
370     return ipc_respond(msg, NULL, 0);
371 }
372 
rpmb_open(const char * rpmb_devname,enum dev_type open_dev_type)373 int rpmb_open(const char* rpmb_devname, enum dev_type open_dev_type) {
374     int rc, sg_version_num;
375     dev_type = open_dev_type;
376 
377     if (dev_type != SOCK_RPMB) {
378         rc = open(rpmb_devname, O_RDWR, 0);
379         if (rc < 0) {
380             ALOGE("unable (%d) to open rpmb device '%s': %s\n", errno, rpmb_devname, strerror(errno));
381             return rc;
382         }
383         rpmb_fd = rc;
384 
385         /* For UFS, it is prudent to check we have a sg device by calling an ioctl */
386         if (dev_type == UFS_RPMB) {
387             if ((ioctl(rpmb_fd, SG_GET_VERSION_NUM, &sg_version_num) < 0) ||
388                 (sg_version_num < RPMB_MIN_SG_VERSION_NUM)) {
389                 ALOGE("%s is not a sg device, or old sg driver\n", rpmb_devname);
390                 return -1;
391             }
392         }
393     } else {
394         struct sockaddr_un unaddr;
395         struct sockaddr *addr = (struct sockaddr *)&unaddr;
396         rc = socket(AF_UNIX, SOCK_STREAM, 0);
397         if (rc < 0) {
398             ALOGE("unable (%d) to create socket: %s\n", errno, strerror(errno));
399             return rc;
400         }
401         rpmb_fd = rc;
402 
403         memset(&unaddr, 0, sizeof(unaddr));
404         unaddr.sun_family = AF_UNIX;
405         // TODO if it overflowed, bail rather than connecting?
406         strncpy(unaddr.sun_path, rpmb_devname, sizeof(unaddr.sun_path)-1);
407         rc = connect(rpmb_fd, addr, sizeof(unaddr));
408         if (rc < 0) {
409             ALOGE("unable (%d) to connect to rpmb socket '%s': %s\n", errno, rpmb_devname, strerror(errno));
410             return rc;
411         }
412     }
413 
414     return 0;
415 }
416 
rpmb_close(void)417 void rpmb_close(void) {
418     close(rpmb_fd);
419     rpmb_fd = -1;
420 }
421