blob: d56b05beb2dac564e6fe1d4908c8bff77f64695c [file] [log] [blame]
Gaurav Shah8bf29d82010-01-28 19:43:24 -08001/* 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.
Gaurav Shah8bf29d82010-01-28 19:43:24 -08004 */
5
Gaurav Shahf5564fa2010-03-02 15:40:01 -08006#include <openssl/pem.h>
Gaurav Shah8bf29d82010-01-28 19:43:24 -08007
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
11
Randall Spangler7c3ae422016-05-11 13:50:18 -070012#include "2sysincludes.h"
13
14#include "2common.h"
Randall Spangler46a382d2016-10-18 12:00:07 -070015#include "2rsa.h"
Randall Spangler7c3ae422016-05-11 13:50:18 -070016#include "2sha.h"
Randall Spangler32a65262011-06-27 10:49:11 -070017#include "host_common.h"
Randall Spangler46a382d2016-10-18 12:00:07 -070018#include "host_signature2.h"
Bill Richardson4e4c1962015-02-03 17:07:15 -080019#include "signature_digest.h"
Randall Spangler32a65262011-06-27 10:49:11 -070020
Randall Spangler46a382d2016-10-18 12:00:07 -070021uint8_t* PrependDigestInfo(enum vb2_hash_algorithm hash_alg, uint8_t* digest)
Randall Spanglerfb267152016-10-11 15:28:16 -070022{
Randall Spangler46a382d2016-10-18 12:00:07 -070023 const int digest_size = vb2_digest_size(hash_alg);
24 uint32_t digestinfo_size = 0;
25 const uint8_t* digestinfo = NULL;
26
27 if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
28 &digestinfo_size))
29 return NULL;
30
Randall Spanglerfb267152016-10-11 15:28:16 -070031 uint8_t* p = malloc(digestinfo_size + digest_size);
Randall Spangler664096b2016-10-13 16:16:41 -070032 memcpy(p, digestinfo, digestinfo_size);
33 memcpy(p + digestinfo_size, digest, digest_size);
Randall Spanglerfb267152016-10-11 15:28:16 -070034 return p;
Gaurav Shah8bf29d82010-01-28 19:43:24 -080035}
36
Gaurav Shah47b593d2010-08-17 15:48:22 -070037uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
Randall Spanglerfb267152016-10-11 15:28:16 -070038 unsigned int algorithm)
39{
40 uint8_t* info_digest = NULL;
Randall Spangler7c3ae422016-05-11 13:50:18 -070041
Randall Spanglerfb267152016-10-11 15:28:16 -070042 uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */
Gaurav Shah8bf29d82010-01-28 19:43:24 -080043
Randall Spangler46a382d2016-10-18 12:00:07 -070044 if (algorithm >= VB2_ALG_COUNT) {
Randall Spanglerfb267152016-10-11 15:28:16 -070045 VBDEBUG(("SignatureDigest() called with invalid algorithm!\n"));
46 } else if (VB2_SUCCESS ==
47 vb2_digest_buffer(buf, len, vb2_crypto_to_hash(algorithm),
48 digest, sizeof(digest))) {
49 info_digest = PrependDigestInfo(algorithm, digest);
50 }
51 return info_digest;
Gaurav Shahf5564fa2010-03-02 15:40:01 -080052}
Gaurav Shah8bf29d82010-01-28 19:43:24 -080053
Gaurav Shah456678b2010-03-10 18:38:45 -080054uint8_t* SignatureBuf(const uint8_t* buf, uint64_t len, const char* key_file,
Randall Spanglerfb267152016-10-11 15:28:16 -070055 unsigned int algorithm)
56{
Randall Spangler46a382d2016-10-18 12:00:07 -070057 const enum vb2_hash_algorithm hash_alg = vb2_crypto_to_hash(algorithm);
Randall Spanglerfb267152016-10-11 15:28:16 -070058 FILE* key_fp = NULL;
59 RSA* key = NULL;
60 uint8_t* signature = NULL;
61 uint8_t* signature_digest = SignatureDigest(buf, len, algorithm);
Randall Spangler46a382d2016-10-18 12:00:07 -070062 if (!signature_digest) {
63 VBDEBUG(("SignatureBuf(): Couldn't get signature digest\n"));
64 return NULL;
65 }
66
67 const int digest_size = vb2_digest_size(hash_alg);
68
69 uint32_t digestinfo_size = 0;
70 const uint8_t* digestinfo = NULL;
71 if (VB2_SUCCESS != vb2_digest_info(hash_alg, &digestinfo,
72 &digestinfo_size)) {
73 VBDEBUG(("SignatureBuf(): Couldn't get digest info\n"));
74 free(signature_digest);
75 return NULL;
76 }
77
78 int signature_digest_len = digest_size + digestinfo_size;
79
Randall Spanglerfb267152016-10-11 15:28:16 -070080 key_fp = fopen(key_file, "r");
81 if (!key_fp) {
82 VBDEBUG(("SignatureBuf(): Couldn't open key file: %s\n",
83 key_file));
84 free(signature_digest);
85 return NULL;
86 }
87 if ((key = PEM_read_RSAPrivateKey(key_fp, NULL, NULL, NULL)))
Randall Spangler46a382d2016-10-18 12:00:07 -070088 signature = (uint8_t *)malloc(
89 vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm)));
Randall Spanglerfb267152016-10-11 15:28:16 -070090 else
91 VBDEBUG(("SignatureBuf(): Couldn't read private key from: %s\n",
92 key_file));
93 if (signature) {
94 if (-1 == RSA_private_encrypt(
95 signature_digest_len, /* Input length. */
96 signature_digest, /* Input data. */
97 signature, /* Output signature. */
98 key, /* Key to use. */
99 RSA_PKCS1_PADDING)) /* Padding to use. */
100 VBDEBUG(("SignatureBuf(): "
101 "RSA_private_encrypt() failed.\n"));
102 }
103 fclose(key_fp);
104 if (key)
105 RSA_free(key);
106 free(signature_digest);
107 return signature;
Gaurav Shah8bf29d82010-01-28 19:43:24 -0800108}