Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 1 | /* Copyright (c) 2011 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 | * Host functions for signature generation. |
| 6 | */ |
| 7 | |
| 8 | #include <openssl/rsa.h> |
| 9 | |
| 10 | #include <stdio.h> |
| 11 | #include <stdlib.h> |
| 12 | #include <sys/types.h> |
| 13 | #include <sys/wait.h> |
| 14 | #include <unistd.h> |
| 15 | |
| 16 | #include "2sysincludes.h" |
| 17 | |
| 18 | #include "2common.h" |
| 19 | #include "2rsa.h" |
| 20 | #include "2sha.h" |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 21 | #include "file_keys.h" |
| 22 | #include "host_common.h" |
| 23 | #include "host_key2.h" |
| 24 | #include "host_signature2.h" |
| 25 | #include "vb2_common.h" |
| 26 | #include "vboot_common.h" |
| 27 | |
| 28 | struct vb2_signature *vb2_alloc_signature(uint32_t sig_size, |
| 29 | uint32_t data_size) |
| 30 | { |
| 31 | struct vb2_signature *sig = (struct vb2_signature *) |
| 32 | calloc(sizeof(*sig) + sig_size, 1); |
| 33 | if (!sig) |
| 34 | return NULL; |
| 35 | |
| 36 | sig->sig_offset = sizeof(*sig); |
| 37 | sig->sig_size = sig_size; |
| 38 | sig->data_size = data_size; |
| 39 | |
| 40 | return sig; |
| 41 | } |
| 42 | |
| 43 | void vb2_init_signature(struct vb2_signature *sig, uint8_t *sig_data, |
| 44 | uint32_t sig_size, uint32_t data_size) |
| 45 | { |
Randall Spangler | 939cc3a | 2016-06-21 15:23:32 -0700 | [diff] [blame] | 46 | memset(sig, 0, sizeof(*sig)); |
| 47 | sig->sig_offset = vb2_offset_of(sig, sig_data); |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 48 | sig->sig_size = sig_size; |
| 49 | sig->data_size = data_size; |
| 50 | } |
| 51 | |
Joel Kitching | e6700f4 | 2019-07-31 14:12:30 +0800 | [diff] [blame] | 52 | vb2_error_t vb2_copy_signature(struct vb2_signature *dest, |
| 53 | const struct vb2_signature *src) |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 54 | { |
| 55 | if (dest->sig_size < src->sig_size) |
| 56 | return VB2_ERROR_SIG_SIZE; |
| 57 | |
| 58 | dest->sig_size = src->sig_size; |
| 59 | dest->data_size = src->data_size; |
| 60 | |
Joel Kitching | 3d8dcc8 | 2019-09-04 15:52:25 +0800 | [diff] [blame] | 61 | memcpy(vb2_signature_data_mutable(dest), |
| 62 | vb2_signature_data(src), |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 63 | src->sig_size); |
| 64 | |
| 65 | return VB2_SUCCESS; |
| 66 | } |
| 67 | |
| 68 | struct vb2_signature *vb2_sha512_signature(const uint8_t *data, uint32_t size) |
| 69 | { |
| 70 | uint8_t digest[VB2_SHA512_DIGEST_SIZE]; |
| 71 | if (VB2_SUCCESS != vb2_digest_buffer(data, size, VB2_HASH_SHA512, |
| 72 | digest, sizeof(digest))) |
| 73 | return NULL; |
| 74 | |
| 75 | struct vb2_signature *sig = |
| 76 | vb2_alloc_signature(VB2_SHA512_DIGEST_SIZE, size); |
| 77 | if (!sig) |
| 78 | return NULL; |
| 79 | |
Joel Kitching | 3d8dcc8 | 2019-09-04 15:52:25 +0800 | [diff] [blame] | 80 | memcpy(vb2_signature_data_mutable(sig), digest, VB2_SHA512_DIGEST_SIZE); |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 81 | return sig; |
| 82 | } |
| 83 | |
| 84 | struct vb2_signature *vb2_calculate_signature( |
| 85 | const uint8_t *data, uint32_t size, |
| 86 | const struct vb2_private_key *key) |
| 87 | { |
| 88 | uint8_t digest[VB2_MAX_DIGEST_SIZE]; |
| 89 | uint32_t digest_size = vb2_digest_size(key->hash_alg); |
| 90 | |
| 91 | uint32_t digest_info_size = 0; |
| 92 | const uint8_t *digest_info = NULL; |
| 93 | if (VB2_SUCCESS != vb2_digest_info(key->hash_alg, |
| 94 | &digest_info, &digest_info_size)) |
| 95 | return NULL; |
| 96 | |
| 97 | /* Calculate the digest */ |
| 98 | if (VB2_SUCCESS != vb2_digest_buffer(data, size, key->hash_alg, |
| 99 | digest, digest_size)) |
| 100 | return NULL; |
| 101 | |
| 102 | /* Prepend the digest info to the digest */ |
| 103 | int signature_digest_len = digest_size + digest_info_size; |
| 104 | uint8_t *signature_digest = malloc(signature_digest_len); |
| 105 | if (!signature_digest) |
| 106 | return NULL; |
| 107 | |
| 108 | memcpy(signature_digest, digest_info, digest_info_size); |
| 109 | memcpy(signature_digest + digest_info_size, digest, digest_size); |
| 110 | |
| 111 | /* Allocate output signature */ |
| 112 | struct vb2_signature *sig = (struct vb2_signature *) |
| 113 | vb2_alloc_signature(vb2_rsa_sig_size(key->sig_alg), size); |
| 114 | if (!sig) { |
| 115 | free(signature_digest); |
| 116 | return NULL; |
| 117 | } |
| 118 | |
| 119 | /* Sign the signature_digest into our output buffer */ |
| 120 | int rv = RSA_private_encrypt(signature_digest_len, /* Input length */ |
| 121 | signature_digest, /* Input data */ |
Joel Kitching | 3d8dcc8 | 2019-09-04 15:52:25 +0800 | [diff] [blame] | 122 | vb2_signature_data_mutable(sig), /* Output sig */ |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 123 | key->rsa_private_key, /* Key to use */ |
| 124 | RSA_PKCS1_PADDING); /* Padding */ |
| 125 | free(signature_digest); |
| 126 | |
| 127 | if (-1 == rv) { |
Randall Spangler | a609478 | 2017-01-20 14:54:47 -0800 | [diff] [blame] | 128 | fprintf(stderr, "%s: RSA_private_encrypt() failed\n", __func__); |
Randall Spangler | 814aaf0 | 2016-06-17 10:48:16 -0700 | [diff] [blame] | 129 | free(sig); |
| 130 | return NULL; |
| 131 | } |
| 132 | |
| 133 | /* Return the signature */ |
| 134 | return sig; |
| 135 | } |