api.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* Copyright (c) 2014 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. * Externally-callable APIs
  6. * (Firmware portion)
  7. */
  8. #include "2sysincludes.h"
  9. #include "2api.h"
  10. #include "2misc.h"
  11. #include "2nvstorage.h"
  12. #include "2secdata.h"
  13. #include "2sha.h"
  14. #include "2rsa.h"
  15. #include "vb2_common.h"
  16. int vb2api_fw_phase3(struct vb2_context *ctx)
  17. {
  18. int rv;
  19. /* Verify firmware keyblock */
  20. rv = vb2_load_fw_keyblock(ctx);
  21. if (rv) {
  22. vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
  23. return rv;
  24. }
  25. /* Verify firmware preamble */
  26. rv = vb2_load_fw_preamble(ctx);
  27. if (rv) {
  28. vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
  29. return rv;
  30. }
  31. return VB2_SUCCESS;
  32. }
  33. int vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, uint32_t *size)
  34. {
  35. struct vb2_shared_data *sd = vb2_get_sd(ctx);
  36. const struct vb2_fw_preamble *pre;
  37. struct vb2_digest_context *dc;
  38. struct vb2_public_key key;
  39. struct vb2_workbuf wb;
  40. int rv;
  41. vb2_workbuf_from_ctx(ctx, &wb);
  42. if (tag == VB2_HASH_TAG_INVALID)
  43. return VB2_ERROR_API_INIT_HASH_TAG;
  44. /* Get preamble pointer */
  45. if (!sd->workbuf_preamble_size)
  46. return VB2_ERROR_API_INIT_HASH_PREAMBLE;
  47. pre = (const struct vb2_fw_preamble *)
  48. (ctx->workbuf + sd->workbuf_preamble_offset);
  49. /* For now, we only support the firmware body tag */
  50. if (tag != VB2_HASH_TAG_FW_BODY)
  51. return VB2_ERROR_API_INIT_HASH_TAG;
  52. /* Allocate workbuf space for the hash */
  53. if (sd->workbuf_hash_size) {
  54. dc = (struct vb2_digest_context *)
  55. (ctx->workbuf + sd->workbuf_hash_offset);
  56. } else {
  57. uint32_t dig_size = sizeof(*dc);
  58. dc = vb2_workbuf_alloc(&wb, dig_size);
  59. if (!dc)
  60. return VB2_ERROR_API_INIT_HASH_WORKBUF;
  61. sd->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc);
  62. sd->workbuf_hash_size = dig_size;
  63. ctx->workbuf_used = sd->workbuf_hash_offset + dig_size;
  64. }
  65. /*
  66. * Work buffer now contains:
  67. * - vb2_shared_data
  68. * - packed firmware data key
  69. * - firmware preamble
  70. * - hash data
  71. */
  72. /*
  73. * Unpack the firmware data key to see which hashing algorithm we
  74. * should use.
  75. *
  76. * TODO: really, the firmware body should be hashed, and not signed,
  77. * because the signature we're checking is already signed as part of
  78. * the firmware preamble. But until we can change the signing scripts,
  79. * we're stuck with a signature here instead of a hash.
  80. */
  81. if (!sd->workbuf_data_key_size)
  82. return VB2_ERROR_API_INIT_HASH_DATA_KEY;
  83. rv = vb2_unpack_key_buffer(&key,
  84. ctx->workbuf + sd->workbuf_data_key_offset,
  85. sd->workbuf_data_key_size);
  86. if (rv)
  87. return rv;
  88. sd->hash_tag = tag;
  89. sd->hash_remaining_size = pre->body_signature.data_size;
  90. if (size)
  91. *size = pre->body_signature.data_size;
  92. if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) {
  93. rv = vb2ex_hwcrypto_digest_init(key.hash_alg,
  94. pre->body_signature.data_size);
  95. if (!rv) {
  96. VB2_DEBUG("Using HW crypto engine for hash_alg %d\n",
  97. key.hash_alg);
  98. dc->hash_alg = key.hash_alg;
  99. dc->using_hwcrypto = 1;
  100. return VB2_SUCCESS;
  101. }
  102. if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED)
  103. return rv;
  104. VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n",
  105. key.hash_alg);
  106. } else {
  107. VB2_DEBUG("HW crypto forbidden by preamble, using SW\n");
  108. }
  109. return vb2_digest_init(dc, key.hash_alg);
  110. }
  111. int vb2api_check_hash_get_digest(struct vb2_context *ctx, void *digest_out,
  112. uint32_t digest_out_size)
  113. {
  114. struct vb2_shared_data *sd = vb2_get_sd(ctx);
  115. struct vb2_digest_context *dc = (struct vb2_digest_context *)
  116. (ctx->workbuf + sd->workbuf_hash_offset);
  117. struct vb2_workbuf wb;
  118. uint8_t *digest;
  119. uint32_t digest_size = vb2_digest_size(dc->hash_alg);
  120. struct vb2_fw_preamble *pre;
  121. struct vb2_public_key key;
  122. int rv;
  123. vb2_workbuf_from_ctx(ctx, &wb);
  124. /* Get preamble pointer */
  125. if (!sd->workbuf_preamble_size)
  126. return VB2_ERROR_API_CHECK_HASH_PREAMBLE;
  127. pre = (struct vb2_fw_preamble *)
  128. (ctx->workbuf + sd->workbuf_preamble_offset);
  129. /* Must have initialized hash digest work area */
  130. if (!sd->workbuf_hash_size)
  131. return VB2_ERROR_API_CHECK_HASH_WORKBUF;
  132. /* Should have hashed the right amount of data */
  133. if (sd->hash_remaining_size)
  134. return VB2_ERROR_API_CHECK_HASH_SIZE;
  135. /* Allocate the digest */
  136. digest = vb2_workbuf_alloc(&wb, digest_size);
  137. if (!digest)
  138. return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
  139. /* Finalize the digest */
  140. if (dc->using_hwcrypto)
  141. rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size);
  142. else
  143. rv = vb2_digest_finalize(dc, digest, digest_size);
  144. if (rv)
  145. return rv;
  146. /* The code below is specific to the body signature */
  147. if (sd->hash_tag != VB2_HASH_TAG_FW_BODY)
  148. return VB2_ERROR_API_CHECK_HASH_TAG;
  149. /*
  150. * The body signature is currently a *signature* of the body data, not
  151. * just its hash. So we need to verify the signature.
  152. */
  153. /* Unpack the data key */
  154. if (!sd->workbuf_data_key_size)
  155. return VB2_ERROR_API_CHECK_HASH_DATA_KEY;
  156. rv = vb2_unpack_key_buffer(&key,
  157. ctx->workbuf + sd->workbuf_data_key_offset,
  158. sd->workbuf_data_key_size);
  159. if (rv)
  160. return rv;
  161. /*
  162. * Check digest vs. signature. Note that this destroys the signature.
  163. * That's ok, because we only check each signature once per boot.
  164. */
  165. rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb);
  166. if (rv)
  167. vb2_fail(ctx, VB2_RECOVERY_FW_BODY, rv);
  168. if (digest_out != NULL) {
  169. if (digest_out_size < digest_size)
  170. return VB2_ERROR_API_CHECK_DIGEST_SIZE;
  171. memcpy(digest_out, digest, digest_size);
  172. }
  173. return rv;
  174. }
  175. int vb2api_check_hash(struct vb2_context *ctx)
  176. {
  177. return vb2api_check_hash_get_digest(ctx, NULL, 0);
  178. }