avb_vbmeta_image.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright (C) 2016 The Android Open Source Project
  4. */
  5. #include "avb_vbmeta_image.h"
  6. #include "avb_crypto.h"
  7. #include "avb_rsa.h"
  8. #include "avb_sha.h"
  9. #include "avb_util.h"
  10. #include "avb_version.h"
  11. AvbVBMetaVerifyResult avb_vbmeta_image_verify(
  12. const uint8_t* data,
  13. size_t length,
  14. const uint8_t** out_public_key_data,
  15. size_t* out_public_key_length) {
  16. AvbVBMetaVerifyResult ret;
  17. AvbVBMetaImageHeader h;
  18. uint8_t* computed_hash;
  19. const AvbAlgorithmData* algorithm;
  20. AvbSHA256Ctx sha256_ctx;
  21. AvbSHA512Ctx sha512_ctx;
  22. const uint8_t* header_block;
  23. const uint8_t* authentication_block;
  24. const uint8_t* auxiliary_block;
  25. int verification_result;
  26. ret = AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER;
  27. if (out_public_key_data != NULL) {
  28. *out_public_key_data = NULL;
  29. }
  30. if (out_public_key_length != NULL) {
  31. *out_public_key_length = 0;
  32. }
  33. /* Before we byteswap or compare Magic, ensure length is long enough. */
  34. if (length < sizeof(AvbVBMetaImageHeader)) {
  35. avb_error("Length is smaller than header.\n");
  36. goto out;
  37. }
  38. /* Ensure magic is correct. */
  39. if (avb_safe_memcmp(data, AVB_MAGIC, AVB_MAGIC_LEN) != 0) {
  40. avb_error("Magic is incorrect.\n");
  41. goto out;
  42. }
  43. avb_vbmeta_image_header_to_host_byte_order((const AvbVBMetaImageHeader*)data,
  44. &h);
  45. /* Ensure we don't attempt to access any fields if we do not meet
  46. * the specified minimum version of libavb.
  47. */
  48. if ((h.required_libavb_version_major != AVB_VERSION_MAJOR) ||
  49. (h.required_libavb_version_minor > AVB_VERSION_MINOR)) {
  50. avb_error("Mismatch between image version and libavb version.\n");
  51. ret = AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION;
  52. goto out;
  53. }
  54. /* Ensure |release_string| ends with a NUL byte. */
  55. if (h.release_string[AVB_RELEASE_STRING_SIZE - 1] != '\0') {
  56. avb_error("Release string does not end with a NUL byte.\n");
  57. goto out;
  58. }
  59. /* Ensure inner block sizes are multiple of 64. */
  60. if ((h.authentication_data_block_size & 0x3f) != 0 ||
  61. (h.auxiliary_data_block_size & 0x3f) != 0) {
  62. avb_error("Block size is not a multiple of 64.\n");
  63. goto out;
  64. }
  65. /* Ensure block sizes all add up to at most |length|. */
  66. uint64_t block_total = sizeof(AvbVBMetaImageHeader);
  67. if (!avb_safe_add_to(&block_total, h.authentication_data_block_size) ||
  68. !avb_safe_add_to(&block_total, h.auxiliary_data_block_size)) {
  69. avb_error("Overflow while computing size of boot image.\n");
  70. goto out;
  71. }
  72. if (block_total > length) {
  73. avb_error("Block sizes add up to more than given length.\n");
  74. goto out;
  75. }
  76. uintptr_t data_ptr = (uintptr_t)data;
  77. /* Ensure passed in memory doesn't wrap. */
  78. if (!avb_safe_add(NULL, (uint64_t)data_ptr, length)) {
  79. avb_error("Boot image location and length mismatch.\n");
  80. goto out;
  81. }
  82. /* Ensure hash and signature are entirely in the Authentication data block. */
  83. uint64_t hash_end;
  84. if (!avb_safe_add(&hash_end, h.hash_offset, h.hash_size) ||
  85. hash_end > h.authentication_data_block_size) {
  86. avb_error("Hash is not entirely in its block.\n");
  87. goto out;
  88. }
  89. uint64_t signature_end;
  90. if (!avb_safe_add(&signature_end, h.signature_offset, h.signature_size) ||
  91. signature_end > h.authentication_data_block_size) {
  92. avb_error("Signature is not entirely in its block.\n");
  93. goto out;
  94. }
  95. /* Ensure public key is entirely in the Auxiliary data block. */
  96. uint64_t pubkey_end;
  97. if (!avb_safe_add(&pubkey_end, h.public_key_offset, h.public_key_size) ||
  98. pubkey_end > h.auxiliary_data_block_size) {
  99. avb_error("Public key is not entirely in its block.\n");
  100. goto out;
  101. }
  102. /* Ensure public key metadata (if set) is entirely in the Auxiliary
  103. * data block. */
  104. if (h.public_key_metadata_size > 0) {
  105. uint64_t pubkey_md_end;
  106. if (!avb_safe_add(&pubkey_md_end,
  107. h.public_key_metadata_offset,
  108. h.public_key_metadata_size) ||
  109. pubkey_md_end > h.auxiliary_data_block_size) {
  110. avb_error("Public key metadata is not entirely in its block.\n");
  111. goto out;
  112. }
  113. }
  114. /* Bail early if there's no hash or signature. */
  115. if (h.algorithm_type == AVB_ALGORITHM_TYPE_NONE) {
  116. ret = AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED;
  117. goto out;
  118. }
  119. /* Ensure algorithm field is supported. */
  120. algorithm = avb_get_algorithm_data(h.algorithm_type);
  121. if (!algorithm) {
  122. avb_error("Invalid or unknown algorithm.\n");
  123. goto out;
  124. }
  125. /* Bail if the embedded hash size doesn't match the chosen algorithm. */
  126. if (h.hash_size != algorithm->hash_len) {
  127. avb_error("Embedded hash has wrong size.\n");
  128. goto out;
  129. }
  130. /* No overflow checks needed from here-on after since all block
  131. * sizes and offsets have been verified above.
  132. */
  133. header_block = data;
  134. authentication_block = header_block + sizeof(AvbVBMetaImageHeader);
  135. auxiliary_block = authentication_block + h.authentication_data_block_size;
  136. switch (h.algorithm_type) {
  137. /* Explicit fall-through: */
  138. case AVB_ALGORITHM_TYPE_SHA256_RSA2048:
  139. case AVB_ALGORITHM_TYPE_SHA256_RSA4096:
  140. case AVB_ALGORITHM_TYPE_SHA256_RSA8192:
  141. avb_sha256_init(&sha256_ctx);
  142. avb_sha256_update(
  143. &sha256_ctx, header_block, sizeof(AvbVBMetaImageHeader));
  144. avb_sha256_update(
  145. &sha256_ctx, auxiliary_block, h.auxiliary_data_block_size);
  146. computed_hash = avb_sha256_final(&sha256_ctx);
  147. break;
  148. /* Explicit fall-through: */
  149. case AVB_ALGORITHM_TYPE_SHA512_RSA2048:
  150. case AVB_ALGORITHM_TYPE_SHA512_RSA4096:
  151. case AVB_ALGORITHM_TYPE_SHA512_RSA8192:
  152. avb_sha512_init(&sha512_ctx);
  153. avb_sha512_update(
  154. &sha512_ctx, header_block, sizeof(AvbVBMetaImageHeader));
  155. avb_sha512_update(
  156. &sha512_ctx, auxiliary_block, h.auxiliary_data_block_size);
  157. computed_hash = avb_sha512_final(&sha512_ctx);
  158. break;
  159. default:
  160. avb_error("Unknown algorithm.\n");
  161. goto out;
  162. }
  163. if (avb_safe_memcmp(authentication_block + h.hash_offset,
  164. computed_hash,
  165. h.hash_size) != 0) {
  166. avb_error("Hash does not match!\n");
  167. ret = AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH;
  168. goto out;
  169. }
  170. verification_result =
  171. avb_rsa_verify(auxiliary_block + h.public_key_offset,
  172. h.public_key_size,
  173. authentication_block + h.signature_offset,
  174. h.signature_size,
  175. authentication_block + h.hash_offset,
  176. h.hash_size,
  177. algorithm->padding,
  178. algorithm->padding_len);
  179. if (verification_result == 0) {
  180. ret = AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH;
  181. goto out;
  182. }
  183. if (h.public_key_size > 0) {
  184. if (out_public_key_data != NULL) {
  185. *out_public_key_data = auxiliary_block + h.public_key_offset;
  186. }
  187. if (out_public_key_length != NULL) {
  188. *out_public_key_length = h.public_key_size;
  189. }
  190. }
  191. ret = AVB_VBMETA_VERIFY_RESULT_OK;
  192. out:
  193. return ret;
  194. }
  195. void avb_vbmeta_image_header_to_host_byte_order(const AvbVBMetaImageHeader* src,
  196. AvbVBMetaImageHeader* dest) {
  197. avb_memcpy(dest, src, sizeof(AvbVBMetaImageHeader));
  198. dest->required_libavb_version_major =
  199. avb_be32toh(dest->required_libavb_version_major);
  200. dest->required_libavb_version_minor =
  201. avb_be32toh(dest->required_libavb_version_minor);
  202. dest->authentication_data_block_size =
  203. avb_be64toh(dest->authentication_data_block_size);
  204. dest->auxiliary_data_block_size =
  205. avb_be64toh(dest->auxiliary_data_block_size);
  206. dest->algorithm_type = avb_be32toh(dest->algorithm_type);
  207. dest->hash_offset = avb_be64toh(dest->hash_offset);
  208. dest->hash_size = avb_be64toh(dest->hash_size);
  209. dest->signature_offset = avb_be64toh(dest->signature_offset);
  210. dest->signature_size = avb_be64toh(dest->signature_size);
  211. dest->public_key_offset = avb_be64toh(dest->public_key_offset);
  212. dest->public_key_size = avb_be64toh(dest->public_key_size);
  213. dest->public_key_metadata_offset =
  214. avb_be64toh(dest->public_key_metadata_offset);
  215. dest->public_key_metadata_size = avb_be64toh(dest->public_key_metadata_size);
  216. dest->descriptors_offset = avb_be64toh(dest->descriptors_offset);
  217. dest->descriptors_size = avb_be64toh(dest->descriptors_size);
  218. dest->rollback_index = avb_be64toh(dest->rollback_index);
  219. dest->flags = avb_be32toh(dest->flags);
  220. }
  221. const char* avb_vbmeta_verify_result_to_string(AvbVBMetaVerifyResult result) {
  222. const char* ret = NULL;
  223. switch (result) {
  224. case AVB_VBMETA_VERIFY_RESULT_OK:
  225. ret = "OK";
  226. break;
  227. case AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED:
  228. ret = "OK_NOT_SIGNED";
  229. break;
  230. case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER:
  231. ret = "INVALID_VBMETA_HEADER";
  232. break;
  233. case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION:
  234. ret = "UNSUPPORTED_VERSION";
  235. break;
  236. case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH:
  237. ret = "HASH_MISMATCH";
  238. break;
  239. case AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH:
  240. ret = "SIGNATURE_MISMATCH";
  241. break;
  242. /* Do not add a 'default:' case here because of -Wswitch. */
  243. }
  244. if (ret == NULL) {
  245. avb_error("Unknown AvbVBMetaVerifyResult value.\n");
  246. ret = "(unknown)";
  247. }
  248. return ret;
  249. }