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 #include "rpmb.h"
18 #include "error_reporting.h"
19 #include "rpmb_protocol.h"
20
21 #include <assert.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <lk/compiler.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <openssl/hmac.h>
31 #include <openssl/mem.h>
32 #include <openssl/rand.h>
33
34 #define RPMB_DEBUG 0
35 #define MAX_PACKET_COUNT 2
36
37 #define RPMB_PROTOCOL_MMC 1
38 #define RPMB_PROTOCOL_UFS 2
39
40 #define RPMB_READ_COUNTER_MAX_RETRIES 3
41
42 #if RPMB_PROTOCOL != RPMB_PROTOCOL_MMC && RPMB_PROTOCOL != RPMB_PROTOCOL_UFS
43 #error "invalid RPMB_PROTOCOL!"
44 #endif
45
46 struct rpmb_state {
47 struct rpmb_key key;
48 void* mmc_handle;
49 uint32_t write_counter;
50 bool first_write_complete;
51 bool verify_failed;
52 };
53
54 #if RPMB_DEBUG
55 #define rpmb_dprintf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
56 #else
57 #define rpmb_dprintf(fmt, ...) \
58 do { \
59 } while (0)
60 #endif
61
rpmb_dprint_buf(const char * prefix,const uint8_t * buf,size_t size)62 static void rpmb_dprint_buf(const char* prefix,
63 const uint8_t* buf,
64 size_t size) {
65 #if RPMB_DEBUG
66 size_t i, j;
67
68 rpmb_dprintf("%s", prefix);
69 for (i = 0; i < size; i++) {
70 if (i && i % 32 == 0) {
71 rpmb_dprintf("\n");
72 j = strlen(prefix);
73 while (j) {
74 rpmb_dprintf(" ");
75 j--;
76 }
77 }
78 rpmb_dprintf(" %02x", buf[i]);
79 }
80 rpmb_dprintf("\n");
81 #endif
82 }
83
rpmb_dprint_u16(const char * prefix,const struct rpmb_u16 u16)84 static void rpmb_dprint_u16(const char* prefix, const struct rpmb_u16 u16) {
85 rpmb_dprint_buf(prefix, u16.byte, sizeof(u16.byte));
86 }
87
rpmb_dprint_u32(const char * prefix,const struct rpmb_u32 u32)88 static void rpmb_dprint_u32(const char* prefix, const struct rpmb_u32 u32) {
89 rpmb_dprint_buf(prefix, u32.byte, sizeof(u32.byte));
90 }
91
rpmb_dprint_key(const char * prefix,const struct rpmb_key key,const char * expected_prefix,const struct rpmb_key expected_key)92 static void rpmb_dprint_key(const char* prefix,
93 const struct rpmb_key key,
94 const char* expected_prefix,
95 const struct rpmb_key expected_key) {
96 #if RPMB_DEBUG
97 rpmb_dprint_buf(prefix, key.byte, sizeof(key.byte));
98 if (CRYPTO_memcmp(key.byte, expected_key.byte, sizeof(key.byte)))
99 rpmb_dprint_buf(expected_prefix, expected_key.byte,
100 sizeof(expected_key.byte));
101 #endif
102 }
103
rpmb_nonce_init(void)104 static struct rpmb_nonce rpmb_nonce_init(void) {
105 struct rpmb_nonce rpmb_nonce;
106
107 RAND_bytes(rpmb_nonce.byte, sizeof(rpmb_nonce.byte));
108
109 return rpmb_nonce;
110 }
111
rpmb_mac(struct rpmb_key key,struct rpmb_packet * packet,size_t packet_count,struct rpmb_key * mac)112 static int rpmb_mac(struct rpmb_key key,
113 struct rpmb_packet* packet,
114 size_t packet_count,
115 struct rpmb_key* mac) {
116 size_t i;
117 int hmac_ret;
118 unsigned int md_len;
119 HMAC_CTX hmac_ctx;
120
121 HMAC_CTX_init(&hmac_ctx);
122 hmac_ret = HMAC_Init_ex(&hmac_ctx, &key, sizeof(key), EVP_sha256(), NULL);
123 if (!hmac_ret) {
124 fprintf(stderr, "HMAC_Init_ex failed\n");
125 goto err;
126 }
127 for (i = 0; i < packet_count; i++) {
128 STATIC_ASSERT(sizeof(*packet) - offsetof(__typeof__(*packet), data) ==
129 284);
130 hmac_ret = HMAC_Update(&hmac_ctx, packet[i].data, 284);
131 if (!hmac_ret) {
132 fprintf(stderr, "HMAC_Update failed\n");
133 goto err;
134 }
135 }
136 hmac_ret = HMAC_Final(&hmac_ctx, mac->byte, &md_len);
137 if (md_len != sizeof(mac->byte)) {
138 fprintf(stderr, "bad md_len %d != %zd\n", md_len, sizeof(mac->byte));
139 exit(1);
140 }
141 if (!hmac_ret) {
142 fprintf(stderr, "HMAC_Final failed\n");
143 goto err;
144 }
145
146 err:
147 HMAC_CTX_cleanup(&hmac_ctx);
148 return hmac_ret ? 0 : -1;
149 }
150
rpmb_check_response(const char * cmd_str,enum rpmb_response response_type,struct rpmb_packet * res,int res_count,struct rpmb_key * mac,struct rpmb_nonce * nonce,uint16_t * addrp,uint32_t write_counter)151 static int rpmb_check_response(const char* cmd_str,
152 enum rpmb_response response_type,
153 struct rpmb_packet* res,
154 int res_count,
155 struct rpmb_key* mac,
156 struct rpmb_nonce* nonce,
157 uint16_t* addrp,
158 uint32_t write_counter) {
159 int i;
160 for (i = 0; i < res_count; i++) {
161 if (rpmb_get_u16(res[i].req_resp) != response_type) {
162 fprintf(stderr, "%s: Bad response type, 0x%x, expected 0x%x\n",
163 cmd_str, rpmb_get_u16(res[i].req_resp), response_type);
164 return -1;
165 }
166
167 if (rpmb_get_u16(res[i].result) != RPMB_RES_OK) {
168 if (rpmb_get_u16(res[i].result) == RPMB_RES_ADDR_FAILURE) {
169 fprintf(stderr, "%s: Addr failure, %u\n", cmd_str,
170 rpmb_get_u16(res[i].address));
171 return -ENOENT;
172 }
173 fprintf(stderr, "%s: Bad result, 0x%x\n", cmd_str,
174 rpmb_get_u16(res[i].result));
175 return -1;
176 }
177
178 if (i == res_count - 1 && mac &&
179 CRYPTO_memcmp(res[i].key_mac.byte, mac->byte, sizeof(mac->byte))) {
180 fprintf(stderr, "%s: Bad MAC\n", cmd_str);
181 error_report_rpmb_mac_mismatch();
182 return -1;
183 }
184
185 if (nonce && CRYPTO_memcmp(res[i].nonce.byte, nonce->byte,
186 sizeof(nonce->byte))) {
187 fprintf(stderr, "%s: Bad nonce\n", cmd_str);
188 return -1;
189 }
190
191 if (write_counter &&
192 write_counter != rpmb_get_u32(res[i].write_counter)) {
193 fprintf(stderr, "%s: Bad write counter, got %u, expected %u\n",
194 cmd_str, rpmb_get_u32(res[i].write_counter), write_counter);
195 error_report_rpmb_counter_mismatch();
196 return -1;
197 }
198
199 if (addrp && *addrp != rpmb_get_u16(res[i].address)) {
200 fprintf(stderr, "%s: Bad addr, got %u, expected %u\n", cmd_str,
201 rpmb_get_u16(res[i].address), *addrp);
202 error_report_rpmb_addr_mismatch();
203 return -1;
204 }
205 }
206
207 return 0;
208 }
209
rpmb_program_key(struct rpmb_state * state,const struct rpmb_key * key)210 int rpmb_program_key(struct rpmb_state* state, const struct rpmb_key* key) {
211 int ret;
212 struct rpmb_packet cmd = {
213 .req_resp = rpmb_u16(RPMB_REQ_PROGRAM_KEY),
214 };
215 struct rpmb_packet rescmd = {
216 .req_resp = rpmb_u16(RPMB_REQ_RESULT_READ),
217 };
218 struct rpmb_packet res;
219
220 memcpy(cmd.key_mac.byte, key->byte, sizeof(cmd.key_mac.byte));
221
222 ret = rpmb_send(state->mmc_handle, &cmd, sizeof(cmd), &rescmd,
223 sizeof(rescmd), &res, sizeof(res), false, false);
224 if (ret < 0)
225 return ret;
226
227 rpmb_dprint_key(" key/mac ", res.key_mac, " expected mac ",
228 res.key_mac);
229 rpmb_dprint_buf(" nonce ", res.nonce.byte, sizeof(res.nonce.byte));
230 rpmb_dprint_u32(" write_counter ", res.write_counter);
231 rpmb_dprint_u16(" result ", res.result);
232 rpmb_dprint_u16(" req/resp ", res.req_resp);
233
234 ret = rpmb_check_response("program key", RPMB_RESP_PROGRAM_KEY, &res, 1,
235 NULL, NULL, NULL, 0);
236 return ret;
237 }
238
rpmb_read_counter(struct rpmb_state * state,uint32_t * write_counter)239 static int rpmb_read_counter(struct rpmb_state* state,
240 uint32_t* write_counter) {
241 int ret;
242 struct rpmb_key mac;
243 struct rpmb_nonce nonce = rpmb_nonce_init();
244 struct rpmb_packet cmd = {
245 .nonce = nonce,
246 .req_resp = rpmb_u16(RPMB_REQ_GET_COUNTER),
247 };
248 struct rpmb_packet res;
249
250 ret = rpmb_send(state->mmc_handle, NULL, 0, &cmd, sizeof(cmd), &res,
251 sizeof(res), false, false);
252 if (ret < 0)
253 return ret;
254
255 ret = rpmb_mac(state->key, &res, 1, &mac);
256 if (ret < 0)
257 return ret;
258
259 rpmb_dprintf("rpmb: read counter response:\n");
260 rpmb_dprint_key(" key/mac ", res.key_mac, " expected mac ", mac);
261 rpmb_dprint_buf(" nonce ", res.nonce.byte, sizeof(res.nonce.byte));
262 rpmb_dprint_u32(" write_counter ", res.write_counter);
263 rpmb_dprint_u16(" result ", res.result);
264 rpmb_dprint_u16(" req/resp ", res.req_resp);
265
266 ret = rpmb_check_response("read counter", RPMB_RESP_GET_COUNTER, &res, 1,
267 &mac, &nonce, NULL, 0);
268 if (ret < 0)
269 return ret;
270
271 if (write_counter)
272 *write_counter = rpmb_get_u32(res.write_counter);
273
274 return 0;
275 }
276
rpmb_read_counter_retry(struct rpmb_state * state,uint32_t * write_counter)277 static int rpmb_read_counter_retry(struct rpmb_state* state,
278 uint32_t* write_counter) {
279 int retries;
280 int ret = 0;
281 for (retries = 0; retries < RPMB_READ_COUNTER_MAX_RETRIES; retries++) {
282 ret = rpmb_read_counter(state, write_counter);
283 if (ret >= 0) {
284 return ret;
285 }
286 }
287
288 /* Return the last error */
289 error_report_rpmb_counter_read_failure();
290 return ret;
291 }
292
rpmb_read_data(struct rpmb_state * state,const void * cmp_buf,void * out_buf,uint16_t addr,uint16_t count,struct rpmb_key * mac)293 static int rpmb_read_data(struct rpmb_state* state,
294 const void* cmp_buf,
295 void* out_buf,
296 uint16_t addr,
297 uint16_t count,
298 struct rpmb_key* mac) {
299 int i;
300 int ret;
301 struct rpmb_nonce nonce = rpmb_nonce_init();
302 struct rpmb_packet cmd = {
303 .nonce = nonce,
304 .address = rpmb_u16(addr),
305 #if RPMB_PROTOCOL == RPMB_PROTOCOL_UFS
306 .block_count = rpmb_u16(count),
307 #endif
308 .req_resp = rpmb_u16(RPMB_REQ_DATA_READ),
309 };
310 struct rpmb_packet res[MAX_PACKET_COUNT];
311 const uint8_t* cmp_bufp;
312 uint8_t* out_bufp;
313
314 assert(count <= MAX_PACKET_COUNT);
315
316 if (!state)
317 return -EINVAL;
318 if (state->verify_failed)
319 return -EIO;
320
321 ret = rpmb_send(state->mmc_handle, NULL, 0, &cmd, sizeof(cmd), res,
322 sizeof(res[0]) * count, false, false);
323 if (ret < 0)
324 return ret;
325
326 if (mac) {
327 ret = rpmb_mac(state->key, res, count, mac);
328 if (ret < 0)
329 return ret;
330 }
331
332 rpmb_dprintf("rpmb: read data, addr %d, count %d, response:\n", addr,
333 count);
334 for (i = 0; i < count; i++) {
335 rpmb_dprintf(" block %d\n", i);
336 if (i == count - 1 && mac)
337 rpmb_dprint_key(" key/mac ", res[i].key_mac,
338 " expected mac ", *mac);
339 rpmb_dprint_buf(" data ", res[i].data, sizeof(res[i].data));
340 rpmb_dprint_buf(" nonce ", res[i].nonce.byte,
341 sizeof(res[i].nonce.byte));
342 rpmb_dprint_u16(" address ", res[i].address);
343 rpmb_dprint_u16(" block_count ", res[i].block_count);
344 rpmb_dprint_u16(" result ", res[i].result);
345 rpmb_dprint_u16(" req/resp ", res[i].req_resp);
346 }
347
348 ret = rpmb_check_response("read data", RPMB_RESP_DATA_READ, res, count, mac,
349 &nonce, &addr, 0);
350 if (ret < 0)
351 return ret;
352
353 if (cmp_buf) {
354 for (cmp_bufp = cmp_buf, i = 0; i < count;
355 i++, cmp_bufp += sizeof(res[i].data)) {
356 if (memcmp(cmp_bufp, res[i].data, sizeof(res[i].data))) {
357 fprintf(stderr, "verify read: data compare failed\n");
358 return -1;
359 }
360 }
361 }
362
363 if (out_buf) {
364 for (out_bufp = out_buf, i = 0; i < count;
365 i++, out_bufp += sizeof(res[i].data)) {
366 memcpy(out_bufp, res[i].data, sizeof(res[i].data));
367 }
368 }
369
370 return 0;
371 }
372
rpmb_read(struct rpmb_state * state,void * buf,uint16_t addr,uint16_t count)373 int rpmb_read(struct rpmb_state* state,
374 void* buf,
375 uint16_t addr,
376 uint16_t count) {
377 struct rpmb_key mac;
378 return rpmb_read_data(state, NULL, buf, addr, count, &mac);
379 }
380
rpmb_read_no_mac(struct rpmb_state * state,void * buf,uint16_t addr,uint16_t count)381 int rpmb_read_no_mac(struct rpmb_state* state,
382 void* buf,
383 uint16_t addr,
384 uint16_t count) {
385 return rpmb_read_data(state, NULL, buf, addr, count, NULL);
386 }
387
rpmb_verify(struct rpmb_state * state,const void * buf,uint16_t addr,uint16_t count)388 int rpmb_verify(struct rpmb_state* state,
389 const void* buf,
390 uint16_t addr,
391 uint16_t count) {
392 struct rpmb_key mac;
393 return rpmb_read_data(state, buf, NULL, addr, count, &mac);
394 }
395
396 /**
397 * check_write_counter() - Check that the write counter matches
398 * @expected_write_counter
399 * @state: Current RPMB state
400 * @expected_write_counter: Write counter we expect
401 *
402 * Return: %true if the write counter is confirmed to be
403 * @expected_write_counter
404 */
check_write_counter(struct rpmb_state * state,uint32_t expected_write_counter)405 static bool check_write_counter(struct rpmb_state* state,
406 uint32_t expected_write_counter) {
407 /*
408 * Query the RPMB chip for the current write counter. Although there was
409 * some sort of exceptional condition, we don't actually know if a
410 * write went through and therefore the counter was incremented.
411 */
412 int ret;
413 uint32_t new_write_counter = 0;
414 ret = rpmb_read_counter_retry(state, &new_write_counter);
415 if (ret == 0) {
416 if (new_write_counter == expected_write_counter) {
417 return true;
418 } else {
419 fprintf(stderr,
420 "%s: Could not resync write counter. "
421 "expected write counter: %u, queried write counter: %u\n",
422 __func__, expected_write_counter, new_write_counter);
423 }
424 } else {
425 fprintf(stderr, "%s: rpmb_read_counter failed: %d\n", __func__, ret);
426 }
427
428 return false;
429 }
430
rpmb_write_data(struct rpmb_state * state,const char * buf,uint16_t addr,uint16_t count,bool sync,bool sync_checkpoint)431 static int rpmb_write_data(struct rpmb_state* state,
432 const char* buf,
433 uint16_t addr,
434 uint16_t count,
435 bool sync,
436 bool sync_checkpoint) {
437 int i;
438 int ret;
439 struct rpmb_key mac;
440 struct rpmb_packet cmd[MAX_PACKET_COUNT];
441 struct rpmb_packet rescmd = {
442 .req_resp = rpmb_u16(RPMB_REQ_RESULT_READ),
443 };
444 struct rpmb_packet res;
445
446 assert(count <= MAX_PACKET_COUNT);
447
448 rpmb_dprintf("rpmb: write data, addr %d, count %d\n", addr, count);
449 for (i = 0; i < count; i++) {
450 memset(&cmd[i], 0, sizeof(cmd[i]));
451 memcpy(cmd[i].data, buf + i * sizeof(cmd[i].data), sizeof(cmd[i].data));
452 rpmb_dprint_buf(" data ", cmd[i].data, sizeof(cmd[i].data));
453 cmd[i].write_counter = rpmb_u32(state->write_counter);
454 cmd[i].address = rpmb_u16(addr);
455 cmd[i].block_count = rpmb_u16(count);
456 cmd[i].req_resp = rpmb_u16(RPMB_REQ_DATA_WRITE);
457 }
458 ret = rpmb_mac(state->key, cmd, count, &cmd[count - 1].key_mac);
459 if (ret < 0) {
460 fprintf(stderr, "rpmb command mac failed\n");
461 return ret;
462 }
463
464 ret = rpmb_send(state->mmc_handle, cmd, sizeof(cmd[0]) * count, &rescmd,
465 sizeof(rescmd), &res, sizeof(res), sync, sync_checkpoint);
466 if (ret < 0) {
467 fprintf(stderr, "rpmb send failed: %d, result: %hu\n", ret,
468 rpmb_get_u16(res.result));
469 goto err_sent;
470 }
471
472 ret = rpmb_mac(state->key, &res, 1, &mac);
473 if (ret < 0) {
474 fprintf(stderr, "rpmb response mac failed\n");
475 goto err_sent;
476 }
477
478 rpmb_dprintf(
479 "rpmb: write data, addr %d, count %d, write_counter %d, response\n",
480 addr, count, state->write_counter);
481 rpmb_dprint_key(" key/mac ", res.key_mac, " expected mac ", mac);
482 rpmb_dprint_buf(" nonce ", res.nonce.byte, sizeof(res.nonce.byte));
483 rpmb_dprint_u32(" write_counter ", res.write_counter);
484 rpmb_dprint_u16(" address ", res.address);
485 rpmb_dprint_u16(" result ", res.result);
486 rpmb_dprint_u16(" req/resp ", res.req_resp);
487
488 ret = rpmb_check_response("write data", RPMB_RESP_DATA_WRITE, &res, 1, &mac,
489 NULL, &addr, state->write_counter + 1);
490 if (ret < 0) {
491 fprintf(stderr, "rpmb_check_response_failed: %d, result: %hu\n", ret,
492 rpmb_get_u16(res.result));
493 if (check_write_counter(state, state->write_counter + 1)) {
494 state->write_counter++;
495
496 fprintf(stderr,
497 "Write was committed with failed response. New write counter: %u\n",
498 state->write_counter);
499 error_report_rpmb_counter_mismatch_recovered();
500
501 /*
502 * Indicate to block device that the FS state is unknown and a clean
503 * superblock must be written.
504 */
505 ret = -EUCLEAN;
506 }
507
508 goto err_sent;
509 }
510
511 state->write_counter++;
512
513 return 0;
514
515 err_sent:
516 /*
517 * An error occurred after the write request was sent. An attacker might
518 * have saved this write request and might send it to the rpmb device at
519 * any time. Any other write with this write counter value now needs extra
520 * checks to make sure there is no corruption.
521 *
522 * 1. The next write fails.
523 *
524 * 1.1. The failure is a count failure.
525 * A write operation that was previously reported as an error must have
526 * actually been written. The filesystem may now be in a state where is it
527 * not safe to write any other block. The write that actually went through
528 * may have been from a previous write attempt, so we don't know the current
529 * state.
530 *
531 * We pass BLOCK_WRITE_FAILED_UNKNOWN_STATE to block_cache_complete_write()
532 * in this case which causes the block device to queue writes of all
533 * filesystem superblocks before doing any new writes.
534 *
535 * 1.1.1. The block actually written was a super-block.
536 * This means a transaction was committed to disk that the file-system code
537 * thought was aborted. The in-memory view of free blocks will not match the
538 * on disk state. It is not safe to proceed with any other write operations
539 * in this state as the file-system could pick a block to write to that is
540 * not actually free until the super block gets updated again with the
541 * in-memory state.
542 *
543 * We mitigate this case by immediately rewriting a new, valid super-block
544 * with the current in-memory (i.e. not including the current, failing
545 * transaction) state when a super-block write fails. If this second write
546 * fails, we are left with a failed transaction in fs->inital_super_block_tr
547 * and all future writes to this filesystem will fail. If it succeeds we
548 * validate the write in 2.1 below. If the device reboots before completing
549 * the second super-block write attempt, a malicious host can replay this
550 * block on a later boot. In the case of TD filesystems, this can cause
551 * detectable filesystem corruption as data blocks may not match the
552 * super-block now, however, that is allowed. For TP filesystems, the next
553 * data write will be validated as it is the first RPMB write after boot,
554 * and if it fails we abort the service (2.1.1), forcing a reboot and
555 * re-initializing the filesystem state from the now committed super-block.
556 *
557 * It's worth noting that in this case, we may have sent a failed response
558 * to a client for a transaction that was eventually committed.
559 *
560 * 1.1.2. The block actually written was a data block.
561 *
562 * The write must have been to a block that was free, and the transaction
563 * that block was part of could never have been committed. We don't actually
564 * care about this write, but we rewrite the superblock as described in
565 * 1.1.1. because we can't know what was written.
566 *
567 * 1.2. The failure is not reported as count failure.
568 * This can be handled the same way as the inital failure. We now have one
569 * more possible write request that can be saved and written at any time by
570 * an attacker, but it is in the same class as before.
571 *
572 * 2. The next write succeeds.
573 *
574 * 2.1. The same block number and counter value has already been sent.
575 * This success status cannot be trusted. We read back the data to verify.
576 * 2.1.1. Verify failed.
577 * This has the same effect as 1.1. We currently block all further
578 * read/write operations after this point (until reboot or FS re-mount)
579 * because it is not safe to recover from this state in a TP filesystem.
580 *
581 * 2.1.2. Verify passed.
582 * We are back to a normal state.
583 *
584 * 2.2. The same block number and counter has not already been sent.
585 * We are back to a normal state.
586 */
587 fprintf(stderr, "rpmb: write failed for write counter %u\n",
588 state->write_counter);
589 state->first_write_complete = false;
590 return ret;
591 }
592
rpmb_write(struct rpmb_state * state,const void * buf,uint16_t addr,uint16_t count,bool sync,bool sync_checkpoint)593 int rpmb_write(struct rpmb_state* state,
594 const void* buf,
595 uint16_t addr,
596 uint16_t count,
597 bool sync,
598 bool sync_checkpoint) {
599 int ret;
600
601 if (!state)
602 return -EINVAL;
603 if (state->verify_failed)
604 return -EIO;
605
606 ret = rpmb_write_data(state, buf, addr, count, sync, sync_checkpoint);
607 if (ret < 0)
608 return ret;
609
610 if (!state->first_write_complete) {
611 /*
612 * The first write request after reading the write counter could get a
613 * signed response from a different write request. There is no nonce in
614 * the write request, only a write counter. The response could be from
615 * another valid write request we generated on a previous boot that was
616 * not completed. Read back the data and verify that the correct data
617 * was written for this case. Note that this only works if we never
618 * send more than one write request to the non-secure proxy at once. If
619 * we later add support for pipelining rpmb operation we need to verify
620 * the first n write requests here instead, where n is the max pipeline
621 * depth of any build that may have run on the same device. We would
622 * also need ensure that a superblock write request is not sent until
623 * all other write requests have been validated and that an attacker
624 * cannot have any saved write requests to the same filesystem with a
625 * larger write-counter value than the superblock update (e.g. by
626 * repeating a non-superblock write request until only one write
627 * operation remains to be verified).
628 */
629 ret = rpmb_verify(state, buf, addr, count);
630 if (ret < 0) {
631 fprintf(stderr,
632 "rpmb write verify failure: %d, addr: %hu, count: %hu\n",
633 ret, addr, count);
634 state->verify_failed = true;
635 return ret;
636 }
637 state->first_write_complete = true;
638 }
639
640 return 0;
641 }
642
rpmb_set_key(struct rpmb_state * state,const struct rpmb_key * key)643 void rpmb_set_key(struct rpmb_state* state, const struct rpmb_key* key) {
644 assert(state);
645 state->key = *key;
646
647 /*
648 * We need to read the counter before reading the super blocks. If an
649 * attacker writes to a super block after we read it, but before we read the
650 * write counter, or next write would succeed without us detecting that the
651 * in-memory super block does not match the on-disk state.
652 *
653 * We retry reading the write counter several times because
654 * we occasionally get an incorrect response
655 */
656 int ret;
657 ret = rpmb_read_counter_retry(state, &state->write_counter);
658 if (ret < 0) {
659 fprintf(stderr, "failed to read rpmb write counter\n");
660 /*
661 * Ignore errors. Any future write will fail since we initialized the
662 * write_counter with the value where it expires.
663 */
664 }
665 }
666
rpmb_init(struct rpmb_state ** statep,void * mmc_handle)667 int rpmb_init(struct rpmb_state** statep, void* mmc_handle) {
668 struct rpmb_state* state = malloc(sizeof(*state));
669 if (!state)
670 return -ENOMEM;
671
672 state->mmc_handle = mmc_handle;
673 state->write_counter = RPMB_WRITE_COUNTER_EXPIRED_VALUE;
674 /*
675 * We don't know if the last write before reboot completed successfully.
676 * There may be writes for the current write counter that can be replayed at
677 * this point, so we need to validate our next write.
678 */
679 state->first_write_complete = false;
680 state->verify_failed = false;
681
682 *statep = state;
683
684 return 0;
685 }
686
rpmb_uninit(struct rpmb_state * statep)687 void rpmb_uninit(struct rpmb_state* statep) {
688 free(statep);
689 }
690