bdb_extend.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* Copyright 2016 The Chromium OS Authors. All rights reserved.
  2. * Use of this source code is governed by a BSD-style license that can be
  3. * found in the LICENSE file.
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include "2sha.h"
  10. #include "bdb.h"
  11. #include "bdb_api.h"
  12. #include "host.h"
  13. static f_extend extend = vb2_sha256_extend;
  14. static void help(void)
  15. {
  16. fprintf(stderr,
  17. "Usage: bdb_extend -b bdb_file -s bds_file "
  18. "[-d digest_file] [-m]\n"
  19. "\n"
  20. "Extends BDS based on a given BDB. When '-m' is given, a "
  21. "MVMAP2315's sha256_extend algorithm will be used. When "
  22. "digest_file is specified, the validity of the BDB key is "
  23. "checked and the secrets will be derived differently.\n");
  24. }
  25. #define PACK32(str, x) \
  26. { \
  27. *(x) = ((uint32_t) *((str) + 3) ) \
  28. | ((uint32_t) *((str) + 2) << 8) \
  29. | ((uint32_t) *((str) + 1) << 16) \
  30. | ((uint32_t) *((str) + 0) << 24); \
  31. }
  32. /**
  33. * MVMAP2315's implementation of sha256 extend
  34. *
  35. * This performs incorrect but still cryptographically secure sha256 extension.
  36. * This is provided for test purpose only.
  37. *
  38. * See vb2_sha256_extend for details on arguments.
  39. */
  40. static void mvmap2315_sha256_extend(const uint8_t *from, const uint8_t *by,
  41. uint8_t *to)
  42. {
  43. struct vb2_sha256_context dc;
  44. int i;
  45. vb2_sha256_init(&dc);
  46. for (i = 0; i < 8; i++) {
  47. PACK32(from, &dc.h[i]);
  48. from += 4;
  49. }
  50. vb2_sha256_update(&dc, by, VB2_SHA256_BLOCK_SIZE);
  51. vb2_sha256_finalize(&dc, to);
  52. }
  53. static void dump_secret(const uint8_t *secret, const char *label)
  54. {
  55. int i;
  56. printf("%s = {", label);
  57. for (i = 0; i < BDB_SECRET_SIZE; i++) {
  58. if (i % 8 == 0)
  59. printf("\n\t");
  60. else
  61. printf(" ");
  62. printf("0x%02x,", secret[i]);
  63. }
  64. printf("\n}\n");
  65. }
  66. static void dump_secrets(struct vba_context *ctx, const uint8_t *wsr)
  67. {
  68. dump_secret(ctx->secrets->bdb, "bdb");
  69. dump_secret(ctx->secrets->boot_path, "boot_path");
  70. dump_secret(ctx->secrets->boot_verified, "boot_verified");
  71. dump_secret(ctx->secrets->nvm_wp, "nvm_wp");
  72. dump_secret(ctx->secrets->nvm_rw, "nvm_rw");
  73. dump_secret(wsr, "wsr");
  74. }
  75. static int derive_secrets(struct vba_context *ctx,
  76. const uint8_t *bdb, uint8_t *wsr)
  77. {
  78. struct bdb_secrets secrets;
  79. memset(&secrets, 0, sizeof(secrets));
  80. ctx->secrets = &secrets;
  81. if (vba_extend_secrets_ro(ctx, bdb, wsr, extend)) {
  82. fprintf(stderr, "ERROR: Failed to derive secrets\n");
  83. return -1;
  84. }
  85. fprintf(stderr, "LOG: Secrets are derived as follows\n");
  86. dump_secrets(ctx, wsr);
  87. return 0;
  88. }
  89. int main(int argc, char *argv[])
  90. {
  91. struct vba_context ctx;
  92. uint8_t *bdb, *bds;
  93. uint8_t *key_digest = NULL;
  94. uint32_t bdb_size, bds_size, digest_size;
  95. const char *bdb_file = NULL;
  96. const char *digest_file = NULL;
  97. const char *bds_file = NULL;
  98. int rv;
  99. int opt;
  100. while ((opt = getopt(argc, argv, "b:d:hms:")) != -1) {
  101. switch(opt) {
  102. case 'b':
  103. bdb_file = optarg;
  104. break;
  105. case 'd':
  106. digest_file = optarg;
  107. break;
  108. case 'h':
  109. help();
  110. return 0;
  111. case 'm':
  112. extend = mvmap2315_sha256_extend;
  113. break;
  114. case 's':
  115. bds_file = optarg;
  116. break;
  117. default:
  118. help();
  119. return -1;
  120. }
  121. }
  122. if (!bdb_file || !bds_file) {
  123. fprintf(stderr, "ERROR: BDB and BDS aren't specified\n\n");
  124. help();
  125. return -1;
  126. }
  127. /* Read BDB */
  128. bdb = read_file(bdb_file, &bdb_size);
  129. if (!bdb) {
  130. fprintf(stderr, "ERROR: Unable to read %s\n", bdb_file);
  131. return -1;
  132. }
  133. /* Read BDS */
  134. bds = read_file(bds_file, &bds_size);
  135. if (!bds) {
  136. fprintf(stderr, "ERROR: Unable to read %s\n", bds_file);
  137. return -1;
  138. }
  139. if (bds_size != BDB_SECRET_SIZE) {
  140. fprintf(stderr, "ERROR: Invalid BDS size: %d\n", bds_size);
  141. return -1;
  142. }
  143. /* Read key digest if provided */
  144. if (digest_file) {
  145. key_digest = read_file(digest_file, &digest_size);
  146. if (!key_digest) {
  147. fprintf(stderr,
  148. "ERROR: Unable to read %s\n", digest_file);
  149. return -1;
  150. }
  151. }
  152. /* Verify BDB and set a flag based on the result */
  153. memset(&ctx, 0, sizeof(ctx));
  154. rv = bdb_verify(bdb, bdb_size, key_digest);
  155. if (rv) {
  156. if (rv != BDB_GOOD_OTHER_THAN_KEY) {
  157. fprintf(stderr, "ERROR: BDB is invalid: %d\n", rv);
  158. return -1;
  159. }
  160. fprintf(stderr,
  161. "WARNING: BDB is valid but key digest doesn't match\n");
  162. } else {
  163. ctx.flags |= VBA_CONTEXT_FLAG_BDB_KEY_EFUSED;
  164. fprintf(stderr, "BDB is successfully verified by eFused key\n");
  165. }
  166. /* Derive secrets and dump the values */
  167. return derive_secrets(&ctx, bdb, bds);
  168. }