signature_digest.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Copyright (c) 2010 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. #include <openssl/pem.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include "2sysincludes.h"
  10. #include "2common.h"
  11. #include "2rsa.h"
  12. #include "2sha.h"
  13. #include "host_common.h"
  14. #include "host_signature2.h"
  15. #include "signature_digest.h"
  16. uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest)
  17. {
  18. const int digest_size = vb2_digest_size(hash_alg);
  19. uint32_t digestinfo_size = 0;
  20. const uint8_t* digestinfo = NULL;
  21. if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
  22. &digestinfo_size))
  23. return NULL;
  24. uint8_t* p = malloc(digestinfo_size + digest_size);
  25. memcpy(p, digestinfo, digestinfo_size);
  26. memcpy(p + digestinfo_size, digest, digest_size);
  27. return p;
  28. }
  29. uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
  30. unsigned int algorithm)
  31. {
  32. uint8_t* info_digest = NULL;
  33. uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */
  34. if (algorithm >= VB2_ALG_COUNT) {
  35. fprintf(stderr, "SignatureDigest(): "
  36. "Called with invalid algorithm!\n");
  37. } else if (VB2_SUCCESS ==
  38. vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm),
  39. digest, sizeof(digest))) {
  40. info_digest = PrependDigestInfo(algorithm, digest);
  41. }
  42. return info_digest;
  43. }
  44. uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
  45. unsigned int algorithm)
  46. {
  47. const enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
  48. FILE* key_fp = NULL;
  49. RSA* key = NULL;
  50. uint8_t* signature = NULL;
  51. uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
  52. if (!signature_digest) {
  53. fprintf(stderr, "SignatureBuf(): "
  54. "Couldn't get signature digest\n");
  55. return NULL;
  56. }
  57. const int digest_size = vb2_digest_size(hash_alg);
  58. uint32_t digestinfo_size = 0;
  59. const uint8_t* digestinfo = NULL;
  60. if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
  61. &digestinfo_size)) {
  62. fprintf(stderr, "SignatureBuf(): Couldn't get digest info\n");
  63. free(signature_digest);
  64. return NULL;
  65. }
  66. int signature_digest_len = digest_size + digestinfo_size;
  67. key_fp = fopen(key_file, "r");
  68. if (!key_fp) {
  69. fprintf(stderr, "SignatureBuf(): Couldn't open key file: %s\n",
  70. key_file);
  71. free(signature_digest);
  72. return NULL;
  73. }
  74. if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
  75. signature = (uint8_t *)malloc(
  76. vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm)));
  77. else
  78. fprintf(stderr, "SignatureBuf(): "
  79. "Couldn't read private key from: %s\n", key_file);
  80. if (signature) {
  81. if (-1 == RSA_private_encrypt(
  82. signature_digest_len, /* Input length. */
  83. signature_digest, /* Input data. */
  84. signature, /* Output signature. */
  85. key, /* Key to use. */
  86. RSA_PKCS1_PADDING)) /* Padding to use. */
  87. fprintf(stderr, "SignatureBuf(): "
  88. "RSA_private_encrypt() failed.\n");
  89. }
  90. fclose(key_fp);
  91. if (key)
  92. RSA_free(key);
  93. free(signature_digest);
  94. return signature;
  95. }