flash.c revision 5621248d744a52a11ea927d7508d71cde44b63cd
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 <sys/mman.h>
35
36#include "flash.h"
37#include "protocol.h"
38#include "debug.h"
39#include "utils.h"
40#include "commands/partitions.h"
41
42#ifdef FLASH_CERT
43#include "secure.h"
44#endif
45
46#define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
47#define BUFFER_SIZE 1024 * 1024
48#define MIN(a, b) (a > b ? b : a)
49
50
51int flash_find_entry(const char *name, char *out, size_t outlen)
52{
53//TODO: Assumption: All the partitions has they unique name
54
55    const char *path = fastboot_getvar("device-directory");
56    size_t length;
57    if (strcmp(path, "") == 0) {
58        D(ERR, "device-directory: not defined in config file");
59        return -1;
60    }
61
62    length = strspn(name, ALLOWED_CHARS);
63    if (length != strlen(name)) {
64        D(ERR, "Not allowed char in name: %c", name[length]);
65        return -1;
66    }
67
68    if (snprintf(out, outlen, "%s%s", path, name) >= (int) outlen) {
69        D(ERR, "Too long path to partition file");
70        return -1;
71    }
72
73    if (access(out, F_OK ) == -1) {
74        D(ERR, "could not find partition file %s", name);
75        return -1;
76    }
77
78    return 0;
79}
80
81int flash_erase(int fd)
82{
83    int64_t size;
84    size = get_block_device_size(fd);
85    D(DEBUG, "erase %llu data from %d\n", size, fd);
86
87    return wipe_block_device(fd, size);
88}
89
90int flash_write(int partition_fd, int data_fd, ssize_t size, ssize_t skip)
91{
92    ssize_t written = 0;
93    struct GPT_mapping input;
94    struct GPT_mapping output;
95
96    while (written < size) {
97        int current_size = MIN(size - written, BUFFER_SIZE);
98
99        if (gpt_mmap(&input, written + skip, current_size, data_fd)) {
100            D(ERR, "Error in writing data, unable to map data file %d at %d size %d", size, skip, current_size);
101            return -1;
102        }
103        if (gpt_mmap(&output, written, current_size, partition_fd)) {
104            D(ERR, "Error in writing data, unable to map output partition");
105            return -1;
106        }
107
108        memcpy(output.ptr, input.ptr, current_size);
109
110        gpt_unmap(&input);
111        gpt_unmap(&output);
112
113        written += current_size;
114    }
115
116    return 0;
117}
118
119#ifdef FLASH_CERT
120
121int flash_validate_certificate(int signed_fd, int *data_fd) {
122    int ret = 0;
123    const char *cert_path;
124    X509_STORE *store = NULL;
125    CMS_ContentInfo *content_info;
126    BIO *content;
127
128    cert_path = fastboot_getvar("certificate-path");
129    if (!strcmp(cert_path, "")) {
130        D(ERR, "could not find cert-key value in config file");
131        goto finish;
132    }
133
134    store = cert_store_from_path(cert_path);
135    if (store == NULL) {
136        D(ERR, "unable to create certification store");
137        goto finish;
138    }
139
140    if (cert_read(signed_fd, &content_info, &content)) {
141        D(ERR, "reading data failed");
142        goto finish;
143    }
144
145    ret = cert_verify(content, content_info, store, data_fd);
146    cert_release(content, content_info);
147
148    return ret;
149
150finish:
151    if (store != NULL)
152        cert_release_store(store);
153
154    return ret;
155}
156
157#else
158int flash_validate_certificate(int signed_fd, int *data_fd) {
159    return 1;
160}
161#endif
162