rsa-verify.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright (c) 2013, Google Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #ifndef USE_HOSTCC
  7. #include <common.h>
  8. #include <fdtdec.h>
  9. #include <asm/types.h>
  10. #include <asm/byteorder.h>
  11. #include <asm/errno.h>
  12. #include <asm/types.h>
  13. #include <asm/unaligned.h>
  14. #include <dm.h>
  15. #else
  16. #include "fdt_host.h"
  17. #include "mkimage.h"
  18. #include <fdt_support.h>
  19. #endif
  20. #include <u-boot/rsa-mod-exp.h>
  21. #include <u-boot/rsa.h>
  22. /* Default public exponent for backward compatibility */
  23. #define RSA_DEFAULT_PUBEXP 65537
  24. /**
  25. * rsa_verify_key() - Verify a signature against some data using RSA Key
  26. *
  27. * Verify a RSA PKCS1.5 signature against an expected hash using
  28. * the RSA Key properties in prop structure.
  29. *
  30. * @prop: Specifies key
  31. * @sig: Signature
  32. * @sig_len: Number of bytes in signature
  33. * @hash: Pointer to the expected hash
  34. * @algo: Checksum algo structure having information on RSA padding etc.
  35. * @return 0 if verified, -ve on error
  36. */
  37. static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
  38. const uint32_t sig_len, const uint8_t *hash,
  39. struct checksum_algo *algo)
  40. {
  41. const uint8_t *padding;
  42. int pad_len;
  43. int ret;
  44. #if !defined(USE_HOSTCC)
  45. struct udevice *mod_exp_dev;
  46. #endif
  47. if (!prop || !sig || !hash || !algo)
  48. return -EIO;
  49. if (sig_len != (prop->num_bits / 8)) {
  50. debug("Signature is of incorrect length %d\n", sig_len);
  51. return -EINVAL;
  52. }
  53. debug("Checksum algorithm: %s", algo->name);
  54. /* Sanity check for stack size */
  55. if (sig_len > RSA_MAX_SIG_BITS / 8) {
  56. debug("Signature length %u exceeds maximum %d\n", sig_len,
  57. RSA_MAX_SIG_BITS / 8);
  58. return -EINVAL;
  59. }
  60. uint8_t buf[sig_len];
  61. #if !defined(USE_HOSTCC)
  62. ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
  63. if (ret) {
  64. printf("RSA: Can't find Modular Exp implementation\n");
  65. return -EINVAL;
  66. }
  67. ret = rsa_mod_exp(mod_exp_dev, sig, sig_len, prop, buf);
  68. #else
  69. ret = rsa_mod_exp_sw(sig, sig_len, prop, buf);
  70. #endif
  71. if (ret) {
  72. debug("Error in Modular exponentation\n");
  73. return ret;
  74. }
  75. padding = algo->rsa_padding;
  76. pad_len = algo->pad_len - algo->checksum_len;
  77. /* Check pkcs1.5 padding bytes. */
  78. if (memcmp(buf, padding, pad_len)) {
  79. debug("In RSAVerify(): Padding check failed!\n");
  80. return -EINVAL;
  81. }
  82. /* Check hash. */
  83. if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) {
  84. debug("In RSAVerify(): Hash check failed!\n");
  85. return -EACCES;
  86. }
  87. return 0;
  88. }
  89. /**
  90. * rsa_verify_with_keynode() - Verify a signature against some data using
  91. * information in node with prperties of RSA Key like modulus, exponent etc.
  92. *
  93. * Parse sign-node and fill a key_prop structure with properties of the
  94. * key. Verify a RSA PKCS1.5 signature against an expected hash using
  95. * the properties parsed
  96. *
  97. * @info: Specifies key and FIT information
  98. * @hash: Pointer to the expected hash
  99. * @sig: Signature
  100. * @sig_len: Number of bytes in signature
  101. * @node: Node having the RSA Key properties
  102. * @return 0 if verified, -ve on error
  103. */
  104. static int rsa_verify_with_keynode(struct image_sign_info *info,
  105. const void *hash, uint8_t *sig,
  106. uint sig_len, int node)
  107. {
  108. const void *blob = info->fdt_blob;
  109. struct key_prop prop;
  110. int length;
  111. int ret = 0;
  112. if (node < 0) {
  113. debug("%s: Skipping invalid node", __func__);
  114. return -EBADF;
  115. }
  116. prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
  117. prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
  118. prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
  119. if (!prop.public_exponent || length < sizeof(uint64_t))
  120. prop.public_exponent = NULL;
  121. prop.exp_len = sizeof(uint64_t);
  122. prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
  123. prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
  124. if (!prop.num_bits || !prop.modulus) {
  125. debug("%s: Missing RSA key info", __func__);
  126. return -EFAULT;
  127. }
  128. ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum);
  129. return ret;
  130. }
  131. int rsa_verify(struct image_sign_info *info,
  132. const struct image_region region[], int region_count,
  133. uint8_t *sig, uint sig_len)
  134. {
  135. const void *blob = info->fdt_blob;
  136. /* Reserve memory for maximum checksum-length */
  137. uint8_t hash[info->algo->checksum->pad_len];
  138. int ndepth, noffset;
  139. int sig_node, node;
  140. char name[100];
  141. int ret;
  142. /*
  143. * Verify that the checksum-length does not exceed the
  144. * rsa-signature-length
  145. */
  146. if (info->algo->checksum->checksum_len >
  147. info->algo->checksum->pad_len) {
  148. debug("%s: invlaid checksum-algorithm %s for %s\n",
  149. __func__, info->algo->checksum->name, info->algo->name);
  150. return -EINVAL;
  151. }
  152. sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
  153. if (sig_node < 0) {
  154. debug("%s: No signature node found\n", __func__);
  155. return -ENOENT;
  156. }
  157. /* Calculate checksum with checksum-algorithm */
  158. ret = info->algo->checksum->calculate(info->algo->checksum->name,
  159. region, region_count, hash);
  160. if (ret < 0) {
  161. debug("%s: Error in checksum calculation\n", __func__);
  162. return -EINVAL;
  163. }
  164. /* See if we must use a particular key */
  165. if (info->required_keynode != -1) {
  166. ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
  167. info->required_keynode);
  168. if (!ret)
  169. return ret;
  170. }
  171. /* Look for a key that matches our hint */
  172. snprintf(name, sizeof(name), "key-%s", info->keyname);
  173. node = fdt_subnode_offset(blob, sig_node, name);
  174. ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
  175. if (!ret)
  176. return ret;
  177. /* No luck, so try each of the keys in turn */
  178. for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node, &ndepth);
  179. (noffset >= 0) && (ndepth > 0);
  180. noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
  181. if (ndepth == 1 && noffset != node) {
  182. ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
  183. noffset);
  184. if (!ret)
  185. break;
  186. }
  187. }
  188. return ret;
  189. }