vb2_helper.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * Copyright 2015 The Chromium OS Authors. All rights reserved.
  3. * Use of this source code is governed by a BSD-style license that can be
  4. * found in the LICENSE file.
  5. */
  6. #define OPENSSL_NO_SHA
  7. #include <openssl/pem.h>
  8. #include "2sysincludes.h"
  9. #include "2common.h"
  10. #include "2id.h"
  11. #include "2rsa.h"
  12. #include "2sha.h"
  13. #include "util_misc.h"
  14. #include "vb21_common.h"
  15. #include "host_common.h"
  16. #include "host_key2.h"
  17. #include "host_misc2.h"
  18. #include "file_type.h"
  19. #include "futility.h"
  20. int vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *alg)
  21. {
  22. const struct vb2_text_vs_enum *entry;
  23. uint32_t val;
  24. char *e;
  25. /* try string first */
  26. entry = vb2_lookup_by_name(vb2_text_vs_hash, str);
  27. if (entry) {
  28. *alg = entry->num;
  29. return 1;
  30. }
  31. /* fine, try number */
  32. val = strtoul(str, &e, 0);
  33. if (!*str || (e && *e))
  34. /* that's not a number */
  35. return 0;
  36. if (!vb2_lookup_by_num(vb2_text_vs_hash, val))
  37. /* That's not a valid alg */
  38. return 0;
  39. *alg = val;
  40. return 1;
  41. }
  42. enum futil_file_type ft_recognize_vb21_key(uint8_t *buf, uint32_t len)
  43. {
  44. struct vb2_public_key pubkey;
  45. struct vb2_private_key *privkey = 0;
  46. /* The pubkey points into buf, so nothing to free */
  47. if (VB2_SUCCESS == vb21_unpack_key(&pubkey, buf, len))
  48. return FILE_TYPE_VB2_PUBKEY;
  49. /* The private key unpacks into new structs */
  50. if (VB2_SUCCESS == vb21_private_key_unpack(&privkey, buf, len)) {
  51. vb2_private_key_free(privkey);
  52. return FILE_TYPE_VB2_PRIVKEY;
  53. }
  54. return FILE_TYPE_UNKNOWN;
  55. }
  56. static inline void vb2_print_bytes(const void *ptr, uint32_t len)
  57. {
  58. const uint8_t *buf = (const uint8_t *)ptr;
  59. int i;
  60. for (i = 0; i < len; i++)
  61. printf("%02x", *buf++);
  62. }
  63. static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest)
  64. {
  65. struct vb21_packed_key *pkey;
  66. if (vb21_public_key_pack(&pkey, key))
  67. return 0;
  68. vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size,
  69. VB2_HASH_SHA1, digest, VB2_SHA1_DIGEST_SIZE);
  70. free(pkey);
  71. return 1;
  72. }
  73. int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len,
  74. void *data)
  75. {
  76. struct vb2_public_key key;
  77. uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
  78. /* The key's members will point into the state buffer after this. Don't
  79. * free anything. */
  80. if (VB2_SUCCESS != vb21_unpack_key(&key, buf, len))
  81. return 1;
  82. printf("Public Key file: %s\n", name);
  83. printf(" Vboot API: 2.1\n");
  84. printf(" Desc: \"%s\"\n", key.desc);
  85. printf(" Signature Algorithm: %d %s\n", key.sig_alg,
  86. vb2_get_sig_algorithm_name(key.sig_alg));
  87. printf(" Hash Algorithm: %d %s\n", key.hash_alg,
  88. vb2_get_hash_algorithm_name(key.hash_alg));
  89. printf(" Version: 0x%08x\n", key.version);
  90. printf(" ID: ");
  91. vb2_print_bytes(key.id, sizeof(*key.id));
  92. printf("\n");
  93. if (vb2_public_key_sha1sum(&key, sha1sum) &&
  94. memcmp(key.id, sha1sum, sizeof(*key.id))) {
  95. printf(" Key sha1sum: ");
  96. vb2_print_bytes(sha1sum, sizeof(sha1sum));
  97. printf("\n");
  98. }
  99. return 0;
  100. }
  101. static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
  102. {
  103. uint8_t *buf;
  104. uint32_t buflen;
  105. if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen))
  106. return 0;
  107. vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest,
  108. VB2_SHA1_DIGEST_SIZE);
  109. free(buf);
  110. return 1;
  111. }
  112. int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len,
  113. void *data)
  114. {
  115. struct vb2_private_key *key = 0;
  116. uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
  117. if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len))
  118. return 1;
  119. printf("Private key file: %s\n", name);
  120. printf(" Vboot API: 2.1\n");
  121. printf(" Desc: \"%s\"\n", key->desc ? key->desc : "");
  122. printf(" Signature Algorithm: %d %s\n", key->sig_alg,
  123. vb2_get_sig_algorithm_name(key->sig_alg));
  124. printf(" Hash Algorithm: %d %s\n", key->hash_alg,
  125. vb2_get_hash_algorithm_name(key->hash_alg));
  126. printf(" ID: ");
  127. vb2_print_bytes(&key->id, sizeof(key->id));
  128. printf("\n");
  129. if (vb2_private_key_sha1sum(key, sha1sum) &&
  130. memcmp(&key->id, sha1sum, sizeof(key->id))) {
  131. printf(" Key sha1sum: ");
  132. vb2_print_bytes(sha1sum, sizeof(sha1sum));
  133. printf("\n");
  134. }
  135. vb2_private_key_free(key);
  136. return 0;
  137. }
  138. static RSA *rsa_from_buffer(uint8_t *buf, uint32_t len)
  139. {
  140. BIO *bp;
  141. RSA *rsa_key;
  142. bp = BIO_new_mem_buf(buf, len);
  143. if (!bp)
  144. return 0;
  145. rsa_key = PEM_read_bio_RSAPrivateKey(bp, NULL, NULL, NULL);
  146. if (!rsa_key) {
  147. if (BIO_reset(bp) < 0)
  148. return 0;
  149. rsa_key = PEM_read_bio_RSA_PUBKEY(bp, NULL, NULL, NULL);
  150. }
  151. if (!rsa_key) {
  152. BIO_free(bp);
  153. return 0;
  154. }
  155. BIO_free(bp);
  156. return rsa_key;
  157. }
  158. enum futil_file_type ft_recognize_pem(uint8_t *buf, uint32_t len)
  159. {
  160. RSA *rsa_key = rsa_from_buffer(buf, len);
  161. if (rsa_key) {
  162. RSA_free(rsa_key);
  163. return FILE_TYPE_PEM;
  164. }
  165. return FILE_TYPE_UNKNOWN;
  166. }
  167. int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
  168. {
  169. RSA *rsa_key;
  170. uint8_t *keyb;
  171. uint8_t digest[VB2_SHA1_DIGEST_SIZE];
  172. uint32_t keyb_len;
  173. int i, bits;
  174. /* We're called only after ft_recognize_pem, so this should work. */
  175. rsa_key = rsa_from_buffer(buf, len);
  176. if (!rsa_key)
  177. DIE;
  178. /* Use to presence of the private exponent to decide if it's public */
  179. printf("%s Key file: %s\n", rsa_key->d ? "Private" : "Public",
  180. name);
  181. bits = BN_num_bits(rsa_key->n);
  182. printf(" Key length: %d\n", bits);
  183. if (vb_keyb_from_rsa(rsa_key, &keyb, &keyb_len)) {
  184. printf(" Key sha1sum: <error>");
  185. RSA_free(rsa_key);
  186. return 1;
  187. }
  188. printf(" Key sha1sum: ");
  189. vb2_digest_buffer(keyb, keyb_len, VB2_HASH_SHA1,
  190. digest, sizeof(digest));
  191. for (i = 0; i < sizeof(digest); i++)
  192. printf("%02x", digest[i]);
  193. printf("\n");
  194. free(keyb);
  195. RSA_free(rsa_key);
  196. return 0;
  197. }