avb_vbmeta_image.c 10 KB

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