Home | History | Annotate | Download | only in commands
      1 /*
      2  * Copyright (c) 2009-2013, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *  * Neither the name of Google, Inc. nor the names of its contributors
     15  *    may be used to endorse or promote products derived from this
     16  *    software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     22  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     25  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/stat.h>
     33 #include <fcntl.h>
     34 #include <inttypes.h>
     35 #include <sys/mman.h>
     36 
     37 #include "flash.h"
     38 #include "protocol.h"
     39 #include "debug.h"
     40 #include "utils.h"
     41 #include "commands/partitions.h"
     42 
     43 #ifdef FLASH_CERT
     44 #include "secure.h"
     45 #endif
     46 
     47 #define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
     48 #define BUFFER_SIZE 1024 * 1024
     49 #define MIN(a, b) (a > b ? b : a)
     50 
     51 
     52 int flash_find_entry(const char *name, char *out, size_t outlen)
     53 {
     54 //TODO: Assumption: All the partitions has they unique name
     55 
     56     const char *path = fastboot_getvar("device-directory");
     57     size_t length;
     58     if (strcmp(path, "") == 0) {
     59         D(ERR, "device-directory: not defined in config file");
     60         return -1;
     61     }
     62 
     63     length = strspn(name, ALLOWED_CHARS);
     64     if (length != strlen(name)) {
     65         D(ERR, "Not allowed char in name: %c", name[length]);
     66         return -1;
     67     }
     68 
     69     if (snprintf(out, outlen, "%s%s", path, name) >= (int) outlen) {
     70         D(ERR, "Too long path to partition file");
     71         return -1;
     72     }
     73 
     74     if (access(out, F_OK ) == -1) {
     75         D(ERR, "could not find partition file %s", name);
     76         return -1;
     77     }
     78 
     79     return 0;
     80 }
     81 
     82 int flash_erase(int fd)
     83 {
     84     int64_t size;
     85     size = get_block_device_size(fd);
     86     D(DEBUG, "erase %"PRId64" data from %d\n", size, fd);
     87 
     88     return wipe_block_device(fd, size);
     89 }
     90 
     91 int flash_write(int partition_fd, int data_fd, ssize_t size, ssize_t skip)
     92 {
     93     ssize_t written = 0;
     94     struct GPT_mapping input;
     95     struct GPT_mapping output;
     96 
     97     while (written < size) {
     98         int current_size = MIN(size - written, BUFFER_SIZE);
     99 
    100         if (gpt_mmap(&input, written + skip, current_size, data_fd)) {
    101             D(ERR, "Error in writing data, unable to map data file %zd at %zd size %d", size, skip, current_size);
    102             return -1;
    103         }
    104         if (gpt_mmap(&output, written, current_size, partition_fd)) {
    105             D(ERR, "Error in writing data, unable to map output partition");
    106             return -1;
    107         }
    108 
    109         memcpy(output.ptr, input.ptr, current_size);
    110 
    111         gpt_unmap(&input);
    112         gpt_unmap(&output);
    113 
    114         written += current_size;
    115     }
    116 
    117     return 0;
    118 }
    119 
    120 #ifdef FLASH_CERT
    121 
    122 int flash_validate_certificate(int signed_fd, int *data_fd) {
    123     int ret = 0;
    124     const char *cert_path;
    125     X509_STORE *store = NULL;
    126     CMS_ContentInfo *content_info;
    127     BIO *content;
    128 
    129     cert_path = fastboot_getvar("certificate-path");
    130     if (!strcmp(cert_path, "")) {
    131         D(ERR, "could not find cert-key value in config file");
    132         goto finish;
    133     }
    134 
    135     store = cert_store_from_path(cert_path);
    136     if (store == NULL) {
    137         D(ERR, "unable to create certification store");
    138         goto finish;
    139     }
    140 
    141     if (cert_read(signed_fd, &content_info, &content)) {
    142         D(ERR, "reading data failed");
    143         goto finish;
    144     }
    145 
    146     ret = cert_verify(content, content_info, store, data_fd);
    147     cert_release(content, content_info);
    148 
    149     return ret;
    150 
    151 finish:
    152     if (store != NULL)
    153         cert_release_store(store);
    154 
    155     return ret;
    156 }
    157 
    158 #else
    159 int flash_validate_certificate(int signed_fd, int *data_fd) {
    160     return 1;
    161 }
    162 #endif
    163