OLD | NEW |
(Empty) | |
| 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 * Host functions for signature generation. |
| 6 */ |
| 7 |
| 8 /* TODO: change all 'return 0', 'return 1' into meaningful return codes */ |
| 9 |
| 10 #define OPENSSL_NO_SHA |
| 11 #include <openssl/engine.h> |
| 12 #include <openssl/pem.h> |
| 13 #include <openssl/rsa.h> |
| 14 |
| 15 #include <stdio.h> |
| 16 #include <stdlib.h> |
| 17 #include <unistd.h> |
| 18 |
| 19 #include "cryptolib.h" |
| 20 #include "file_keys.h" |
| 21 #include "utility.h" |
| 22 #include "vboot_common.h" |
| 23 #include "host_common.h" |
| 24 |
| 25 |
| 26 VbSignature* SignatureAlloc(uint64_t sig_size, uint64_t data_size) { |
| 27 VbSignature* sig = (VbSignature*)Malloc(sizeof(VbSignature) + sig_size); |
| 28 if (!sig) |
| 29 return NULL; |
| 30 |
| 31 sig->sig_offset = sizeof(VbSignature); |
| 32 sig->sig_size = sig_size; |
| 33 sig->data_size = data_size; |
| 34 return sig; |
| 35 } |
| 36 |
| 37 |
| 38 void SignatureInit(VbSignature* sig, uint8_t* sig_data, |
| 39 uint64_t sig_size, uint64_t data_size) { |
| 40 sig->sig_offset = OffsetOf(sig, sig_data); |
| 41 sig->sig_size = sig_size; |
| 42 sig->data_size = data_size; |
| 43 } |
| 44 |
| 45 |
| 46 int SignatureCopy(VbSignature* dest, const VbSignature* src) { |
| 47 if (dest->sig_size < src->sig_size) |
| 48 return 1; |
| 49 dest->sig_size = src->sig_size; |
| 50 dest->data_size = src->data_size; |
| 51 Memcpy(GetSignatureData(dest), GetSignatureDataC(src), src->sig_size); |
| 52 return 0; |
| 53 } |
| 54 |
| 55 |
| 56 VbSignature* CalculateChecksum(const uint8_t* data, uint64_t size) { |
| 57 |
| 58 uint8_t* header_checksum; |
| 59 VbSignature* sig; |
| 60 |
| 61 header_checksum = DigestBuf(data, size, SHA512_DIGEST_ALGORITHM); |
| 62 if (!header_checksum) |
| 63 return NULL; |
| 64 |
| 65 sig = SignatureAlloc(SHA512_DIGEST_SIZE, 0); |
| 66 if (!sig) { |
| 67 Free(header_checksum); |
| 68 return NULL; |
| 69 } |
| 70 sig->sig_offset = sizeof(VbSignature); |
| 71 sig->sig_size = SHA512_DIGEST_SIZE; |
| 72 sig->data_size = size; |
| 73 |
| 74 /* Signature data immediately follows the header */ |
| 75 Memcpy(GetSignatureData(sig), header_checksum, SHA512_DIGEST_SIZE); |
| 76 Free(header_checksum); |
| 77 return sig; |
| 78 } |
| 79 |
| 80 |
| 81 VbSignature* CalculateSignature(const uint8_t* data, uint64_t size, |
| 82 const VbPrivateKey* key) { |
| 83 |
| 84 uint8_t* digest; |
| 85 int digest_size = hash_size_map[key->algorithm]; |
| 86 |
| 87 const uint8_t* digestinfo = hash_digestinfo_map[key->algorithm]; |
| 88 int digestinfo_size = digestinfo_size_map[key->algorithm]; |
| 89 |
| 90 uint8_t* signature_digest; |
| 91 int signature_digest_len = digest_size + digestinfo_size; |
| 92 |
| 93 VbSignature* sig; |
| 94 int rv; |
| 95 |
| 96 /* Calculate the digest */ |
| 97 /* TODO: rename param 3 of DigestBuf to hash_type */ |
| 98 digest = DigestBuf(data, size, hash_type_map[key->algorithm]); |
| 99 if (!digest) |
| 100 return NULL; |
| 101 |
| 102 /* Prepend the digest info to the digest */ |
| 103 signature_digest = Malloc(signature_digest_len); |
| 104 if (!signature_digest) { |
| 105 Free(digest); |
| 106 return NULL; |
| 107 } |
| 108 Memcpy(signature_digest, digestinfo, digestinfo_size); |
| 109 Memcpy(signature_digest + digestinfo_size, digest, digest_size); |
| 110 Free(digest); |
| 111 |
| 112 /* Allocate output signature */ |
| 113 sig = SignatureAlloc(siglen_map[key->algorithm], size); |
| 114 if (!sig) { |
| 115 Free(signature_digest); |
| 116 return NULL; |
| 117 } |
| 118 |
| 119 /* Sign the signature_digest into our output buffer */ |
| 120 rv = RSA_private_encrypt(signature_digest_len, /* Input length */ |
| 121 signature_digest, /* Input data */ |
| 122 GetSignatureData(sig), /* Output sig */ |
| 123 key->rsa_private_key, /* Key to use */ |
| 124 RSA_PKCS1_PADDING); /* Padding to use */ |
| 125 Free(signature_digest); |
| 126 |
| 127 if (-1 == rv) { |
| 128 debug("SignatureBuf(): RSA_private_encrypt() failed.\n"); |
| 129 Free(sig); |
| 130 return NULL; |
| 131 } |
| 132 |
| 133 /* Return the signature */ |
| 134 return sig; |
| 135 } |
OLD | NEW |